<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>Javascript高阶 | CoderT</title><meta name="author" content="CoderT"><meta name="copyright" content="CoderT"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="js高阶">
<meta property="og:type" content="article">
<meta property="og:title" content="Javascript高阶">
<meta property="og:url" content="http://example.com/2022/09/25/JavaScript%E9%AB%98%E9%98%B6/index.html">
<meta property="og:site_name" content="CoderT">
<meta property="og:description" content="js高阶">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg">
<meta property="article:published_time" content="2022-09-25T11:40:37.000Z">
<meta property="article:modified_time" content="2023-09-20T07:20:52.387Z">
<meta property="article:author" content="CoderT">
<meta property="article:tag" content="JavaScript">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="http://example.com/2022/09/25/JavaScript%E9%AB%98%E9%98%B6/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><meta/><meta/><meta/><meta/><meta/><meta/><meta/><meta/><meta/><meta/><meta/><meta/><meta/><meta/><meta/><meta/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = {
  root: '/',
  algolia: undefined,
  localSearch: undefined,
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
  noticeOutdate: {"limitDay":365,"position":"top","messagePrev":"It has been","messageNext":"days since the last update, the content of the article may be outdated."},
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":200},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: true,
    post: true
  },
  runtime: '天',
  dateSuffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: {"limitCount":50,"languages":{"author":"作者: CoderT","link":"链接: ","source":"来源: CoderT","info":"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: true,
  islazyload: false,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: false,
  },
  autoDarkmode: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: 'Javascript高阶',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2023-09-20 15:20:52'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
    win.getCSS = (url,id = false) => new Promise((resolve, reject) => {
      const link = document.createElement('link')
      link.rel = 'stylesheet'
      link.href = url
      if (id) link.id = id
      link.onerror = reject
      link.onload = link.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        link.onload = link.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(link)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><meta name="generator" content="Hexo 6.3.0"></head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><script>(()=>{
  const $loadingBox = document.getElementById('loading-box')
  const $body = document.body
  const preloader = {
    endLoading: () => {
      $body.style.overflow = ''
      $loadingBox.classList.add('loaded')
    },
    initLoading: () => {
      $body.style.overflow = 'hidden'
      $loadingBox.classList.remove('loaded')
    }
  }

  preloader.initLoading()
  window.addEventListener('load',() => { preloader.endLoading() })

  if (false) {
    document.addEventListener('pjax:send', () => { preloader.initLoading() })
    document.addEventListener('pjax:complete', () => { preloader.endLoading() })
  }
})()</script><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/img/avatar.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">2</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">1</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">1</div></a></div><hr class="custom-hr"/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg')"><nav id="nav"><span id="blog-info"><a href="/" title="CoderT"><span class="site-name">CoderT</span></a></span><div id="menus"><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">Javascript高阶</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2022-09-25T11:40:37.000Z" title="发表于 2022-09-25 19:40:37">2022-09-25</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2023-09-20T07:20:52.387Z" title="更新于 2023-09-20 15:20:52">2023-09-20</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E4%B8%AA%E4%BA%BA%E7%AC%94%E8%AE%B0/">个人笔记</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="Javascript高阶"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h2 id="原型"><a href="#原型" class="headerlink" title="原型"></a>原型</h2><ul>
<li>原型的出现，就是为了解决 构造函数的缺点</li>
<li>也就是给我们提供了一个给对象添加函数的方法</li>
</ul>
<h3 id="prototype-显示原型"><a href="#prototype-显示原型" class="headerlink" title="prototype 显示原型"></a>prototype 显示原型</h3><ul>
<li>每个函数天生自带的一个属性，叫 prototype，是一个对象空间</li>
<li>既然每个函数都有，构造函数也是函数，构造函数也有这个对象空间</li>
<li>这个<code>prototype</code>的对象空间可以由函数名来访问</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>); <span class="comment">//是一个对象</span></span><br></pre></td></tr></table></figure>

<ul>
<li>是对象，我们就可以往里面放东西</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// let obj = &#123; &#125;</span></span><br><span class="line"><span class="comment">// obj.name = &quot;xxx&quot;</span></span><br><span class="line"><span class="comment">// obj.sayHi = function()&#123;&#125;</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"><span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">name</span> = <span class="string">&#x27;prototype&#x27;</span>;</span><br><span class="line"><span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sayHi</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;&#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>); <span class="comment">//有属性有方法</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Person</span>.<span class="property">sayHi</span>); <span class="comment">//undefined 访问不到</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> p1 = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(p1.<span class="property">name</span>, p1.<span class="property">sayHi</span>); <span class="comment">//能访问到</span></span><br></pre></td></tr></table></figure>

<ul>
<li>我们发现了一个叫做<code>prototype</code>的空间和函数有关</li>
<li>并且我们可以向里面放一些东西</li>
<li>重点:在函数的 prototype 里面存储的内容，不是给函数本身使用的，是给函数的每一个实例化对象使用的</li>
</ul>
<h3 id="proto-隐式原型"><a href="#proto-隐式原型" class="headerlink" title="__proto__ 隐式原型"></a><code>__proto__</code> 隐式原型</h3><ul>
<li>每个对象天生自带的一个属性，叫做<code>__proto__</code>,也是一个对象空间</li>
<li>既然每个对象都有，实例化对象也是对象，每一个实例化的对象都有这个属性</li>
<li>这个<code>__proto__</code>对象空间是给对象使用的</li>
<li>当你访问对象中的一个属性的时候<ul>
<li>如果这个对象本身有这个属性，那么直接给你结果</li>
<li>如果没有，就会去<code>__proto__</code>这个对象空间里面找，有的话就给你结果</li>
<li>未完待续</li>
</ul>
</li>
<li>那么这个<code>__proto__</code>指向哪里？<br>这个对象由那个构造函数 new 出来<br>那么这个对象的<code>__proto__</code>就指向该构造函数的<code>prototype</code></li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"><span class="keyword">let</span> p = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line"><span class="comment">//p.__proto__和Person.prototype 就是一个空间</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(p.<span class="property">__proto__</span> === <span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>); <span class="comment">//true</span></span><br></pre></td></tr></table></figure>

<ul>
<li>实例化对象的隐式原型和构造函数的显示原型是同一个空间</li>
<li>我们就可以通过构造函数的<code>prototype</code>来给实例化对象添加属性</li>
<li>对象访问属性的时候，可以去自己的<code>__proto__</code>中查找</li>
<li>之前的构造函数不合理的地方就解决了<ul>
<li>我们把对象的方法放在构造函数的<code>prototype</code>上</li>
<li>实例化的对象访问的时候就去自己的<code>__proto__</code></li>
<li>也可以使用</li>
</ul>
</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"><span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sayHi</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;你好&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">let</span> p = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line"><span class="keyword">let</span> p1 = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line">p.<span class="title function_">sayHi</span>();</span><br><span class="line">p1.<span class="title function_">sayHi</span>();</span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">      p本身没有sayHi方法，就去自己的__proto上找</span></span><br><span class="line"><span class="comment">      p.__proto__就是Person.prototype</span></span><br><span class="line"><span class="comment">      我们在上一步 给Person.prototype添加了一个sayHi方法</span></span><br><span class="line"><span class="comment">      p.sayHi()肯定能执行</span></span><br><span class="line"><span class="comment">      */</span></span><br></pre></td></tr></table></figure>

<p>p 和 p1 使用的实际上就是同一个函数</p>
<p><strong>prototype</strong> 和 <code>__proto__</code> 有什么区别</p>
<ol>
<li>名字不一样</li>
<li>有可能指向同一个对象空间<br> &#x3D;&gt; prototype 前面主语一定是函数<br> &#x3D;&gt; <strong>proto</strong> 前面的主语一定是对象</li>
</ol>
<h3 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">      原型:</span></span><br><span class="line"><span class="comment">         显示 prototype</span></span><br><span class="line"><span class="comment">            每一个函数天生自带，是一个对象数据类型</span></span><br><span class="line"><span class="comment">            构造函数也是函数，所以也有prototype</span></span><br><span class="line"><span class="comment">            里面有一个constructor的属性 1. 表明我是谁自带的prototype 2.指向自己的构造函数</span></span><br><span class="line"><span class="comment">            是一个对象，我们可以往里面添加属性</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">         隐式 __proto__</span></span><br><span class="line"><span class="comment">            每个对象天生自带，也是一个对象数据类型</span></span><br><span class="line"><span class="comment">            实例对象也是对象 所以也有__proto__</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">        对象属性的访问规则</span></span><br><span class="line"><span class="comment">          1. 自己有就给你</span></span><br><span class="line"><span class="comment">          2. 自己没有就去__proto__上找 有给你</span></span><br><span class="line"><span class="comment">          没有？？</span></span><br><span class="line"><span class="comment">          3、自己有，实例对象的原型上也有，但不会访问原型上的这种情况被称为&quot;属性遮蔽(property sha)&quot;</span></span><br><span class="line"><span class="comment">      </span></span><br><span class="line"><span class="comment">      以后写构造函数的时候</span></span><br><span class="line"><span class="comment">          属性直接写在函数体内</span></span><br><span class="line"><span class="comment">          方法写在构造函数的显示原型上(挂载) </span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = <span class="string">&#x27;alex&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//给Person的原型上添加了一个属性</span></span><br><span class="line"><span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">a</span> = <span class="number">100</span>;</span><br><span class="line"><span class="comment">//p.__proto__.a=100</span></span><br><span class="line"><span class="keyword">let</span> p = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(p.<span class="property">a</span>); <span class="comment">//100</span></span><br></pre></td></tr></table></figure>

<h3 id="面向对象的开发思想"><a href="#面向对象的开发思想" class="headerlink" title="面向对象的开发思想"></a>面向对象的开发思想</h3><p>核心:<strong>高内聚低耦合</strong></p>
<p>意义:</p>
<ul>
<li>在开发的时候</li>
<li>首先写一个构造函数</li>
<li>这个构造函数可以生成能够完成对应的功能对象</li>
</ul>
<h3 id="原型和原型链"><a href="#原型和原型链" class="headerlink" title="原型和原型链"></a>原型和原型链</h3><ul>
<li><p>原型:每个函数天生自带 prototype 对象数据类型</p>
<ul>
<li>作用：由构造函数 向原型上添加方法，给该构造函数的所有实例对象用</li>
<li>为了解决将方法写在构造函数体内造成的资源浪费</li>
</ul>
</li>
<li><p>原型链：</p>
<ul>
<li>用<code>__proto__</code>串联起来的对象链状结构</li>
<li>作用:为了对象的访问机制服务的</li>
<li>注意:只是<code>__proto__</code>串联起来的对象，千万不要往 prototype 靠</li>
</ul>
</li>
</ul>
<p>万物皆对象</p>
<p>问题</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params">nam, age, gender</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">gender</span> = gender;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sayHi</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;hahah&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">const</span> p1 = <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>, <span class="string">&#x27;男&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(p1);</span><br><span class="line"><span class="comment">//问题一：p1的__proto__是谁？</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(p1.<span class="property">__proto__</span> === <span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>); <span class="comment">//true</span></span><br><span class="line"><span class="comment">//2.  Person的__proto__是谁？</span></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">      Person是构造函数，同时是一个函数 同时也是一个对象</span></span><br><span class="line"><span class="comment">      只要是对象就会有__proto__属性</span></span><br><span class="line"><span class="comment">      js内有一个内置的构造函数叫做Function 只要是函数 都可以看作Function的实例</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Person</span>.<span class="property">__proto__</span> === <span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//3. Person.prototype.__proto__是谁？</span></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">      Person的prototype是函数天生自带的一个对象数据类型</span></span><br><span class="line"><span class="comment">      只要是对象就会有__proto__</span></span><br><span class="line"><span class="comment">      js内有一个内置的构造函数 叫做 Object 只要是对象 都可以看作Object的实例</span></span><br><span class="line"><span class="comment">      Person.prototype对象数据类型 是对象 可以看作Object的实例</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">__proto__</span> === <span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//4. Function 的__proto__？</span></span><br><span class="line"><span class="comment">//Function是一个构造函数，是函数也是对象</span></span><br><span class="line"><span class="comment">//Function自己是自己的实例，自己是自己的构造函数</span></span><br><span class="line"><span class="comment">//js中 他叫做顶级函数</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Function</span>.<span class="property">__proto__</span> === <span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>);</span><br><span class="line"><span class="comment">//5. Function.prototype.__proto__ ?</span></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">      Function.prototype 是函数天生自带一个对象数据类型</span></span><br><span class="line"><span class="comment">      是对象就有__proto__</span></span><br><span class="line"><span class="comment">      把Function.prototype看作Object的实例</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">__proto__</span> === <span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>);</span><br><span class="line"><span class="comment">//6. Object.__proto__?</span></span><br><span class="line"><span class="comment">//Object是构造函数 是对象也是函数</span></span><br><span class="line"><span class="comment">// 只要是对象就有__proto__</span></span><br><span class="line"><span class="comment">// 是构造函数 是函数 是函数 看作Function的实例</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="property">__proto__</span> === <span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>);</span><br><span class="line"><span class="comment">//7.Object.prototype.__proto__?</span></span><br><span class="line"><span class="comment">//Object.prototype是函数天生自带的一个对象数据类型</span></span><br><span class="line"><span class="comment">//是对象 就有__proto__</span></span><br><span class="line"><span class="comment">//在js Object顶级对象 Object.prototype叫做顶级原型</span></span><br><span class="line"><span class="comment">//Object.prototype唯一一个没有__proto__的数据类型</span></span><br><span class="line"><span class="comment">// null</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">__proto__</span>); <span class="comment">//null</span></span><br></pre></td></tr></table></figure>

<h3 id="对象访问机制"><a href="#对象访问机制" class="headerlink" title="对象访问机制"></a>对象访问机制</h3><img src="https://markdown-1317399397.cos.ap-guangzhou.myqcloud.com/%E5%8E%9F%E5%9E%8B%E9%93%BE.jpg" style="zoom: 50%;" />

<p>当你访问一个对象的属性的时候<br>首先在自己身上查找,如果有，给你 停止查找<br>如果没有，<code>__proto__</code>自己去上找<br>如果还没有，再去<code>__proto__</code>上 找<br>依此类推，直到 顶级原型上(Object.prototype)都没有，返回 undefined</p>
<p>结论:<br><strong>Object.prototype</strong> 添加的内容，所有的对象数据类型都可以使用<br><strong>Function.prototype</strong> 添加的内容，所有的函数数据类型都可以使用</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = <span class="string">&#x27;alex&#x27;</span>;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = <span class="number">18</span>;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">gender</span> = <span class="string">&#x27;男&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">a</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Person.prototype&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">b</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Object.prototype&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">c</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Function.prototype&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">const</span> p = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line">p.<span class="title function_">a</span>();</span><br><span class="line">p.<span class="title function_">b</span>();</span><br><span class="line"><span class="comment">// p.c(); 报错</span></span><br><span class="line"><span class="comment">// Person.a();报错</span></span><br><span class="line"><span class="title class_">Person</span>.<span class="title function_">b</span>();</span><br><span class="line"><span class="title class_">Person</span>.<span class="title function_">c</span>();</span><br></pre></td></tr></table></figure>

<p>例题</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">getName</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">5</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> getName;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Father</span>(<span class="params"></span>) &#123;</span><br><span class="line">  getName = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">1</span>);</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="keyword">return</span> <span class="variable language_">this</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">Father</span>.<span class="property">getName</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">2</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="title class_">Father</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">getName</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">3</span>);</span><br><span class="line">&#125;;</span><br><span class="line">getName = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">4</span>);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//对象中的方法</span></span><br><span class="line"><span class="title class_">Father</span>.<span class="title function_">getName</span>(); <span class="comment">//2</span></span><br><span class="line"><span class="comment">//全局的getName方法</span></span><br><span class="line"><span class="title function_">getName</span>(); <span class="comment">//4</span></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Father</span>.<span class="title function_">getName</span>(); <span class="comment">//2 &#123;&#125;</span></span><br><span class="line"><span class="comment">//Father的实例去找getName</span></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Father</span>().<span class="title function_">getName</span>(); <span class="comment">//3 undefined</span></span><br><span class="line"><span class="comment">//new Father()=&gt;实例对象</span></span><br><span class="line"><span class="comment">// new 实例对象.getName()</span></span><br><span class="line"><span class="keyword">new</span> <span class="keyword">new</span> <span class="title class_">Father</span>().<span class="title function_">getName</span>(); <span class="comment">//3 &#123;&#125;</span></span><br></pre></td></tr></table></figure>

<h2 id="继承"><a href="#继承" class="headerlink" title="继承"></a>继承</h2><h3 id="1-认识继承"><a href="#1-认识继承" class="headerlink" title="1. 认识继承"></a>1. 认识继承</h3><p>关于 构造函数 的高阶应用<br>继承是出现在两个构造函数之间的关系</p>
<p>当构造函数 B 的实例，使用了构造函数 A 内书写的属性和方法<br>此时我们就说 构造函数 B 继承自 构造函数 A<br>构造函数 A 是构造函数 B 的父类<br>构造函数 B 是构造函数 A 的子类</p>
<ol>
<li>原型继承</li>
<li>call 继承</li>
<li>组合继承</li>
<li>es6 的继承(完美)</li>
</ol>
<h3 id="2-原型继承"><a href="#2-原型继承" class="headerlink" title="2. 原型继承"></a>2. 原型继承</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//父类</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sayHi</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;hello world&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">//子类</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Student</span>(<span class="params">gender</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">gender</span> = gender;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//当Student构造函数书写完毕后</span></span><br><span class="line"><span class="comment">//此时 会伴生出一个Student.prototype的对象数据类型</span></span><br><span class="line"><span class="comment">//我们可以向Student.prototype添加属性</span></span><br><span class="line"><span class="comment">// Student.prototype.a=100</span></span><br><span class="line"><span class="comment">// 我们也可以重新赋值</span></span><br><span class="line"><span class="comment">//本身你的Student.prototype保存的是一个 对象数据类型的 地址</span></span><br><span class="line"><span class="comment">//我 给你赋值为一个 新的 对象数据类型 的 地址</span></span><br><span class="line"><span class="comment">//就把你本身保存的地址覆盖掉</span></span><br><span class="line"><span class="comment">// const obj = &#123;</span></span><br><span class="line"><span class="comment">//   msg: &#x27;objjjjjj&#x27;,</span></span><br><span class="line"><span class="comment">// &#125;;</span></span><br><span class="line"><span class="comment">// //验证覆盖</span></span><br><span class="line"><span class="comment">// Student.prototype = obj;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//实现继承</span></span><br><span class="line"><span class="title class_">Student</span>.<span class="property"><span class="keyword">prototype</span></span> = <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// Student.prototype = obj;</span></span><br><span class="line"><span class="title class_">Student</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">play</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;没日没夜的玩&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">//目前 s只有play属性和gender属性</span></span><br><span class="line"><span class="comment">//继承就是要s有name和age 还有sayHi</span></span><br><span class="line"><span class="keyword">const</span> s = <span class="keyword">new</span> <span class="title class_">Student</span>(<span class="string">&#x27;男&#x27;</span>);</span><br><span class="line"><span class="comment">// console.log(s.name, s.age, s.sayHi);</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(s);</span><br></pre></td></tr></table></figure>

<ul>
<li>核心:子类原型指向父类的 实例</li>
<li>子类.prototype &#x3D; new 父类</li>
</ul>
<p>优缺点<br><strong>优点</strong>:父类的 构造函数体内 和 原型上的所有内容都能继承</p>
<p><strong>缺点</strong>:继承下来的属性不在自己身上，子类的实例的所有属性分开了两部分书写，s 自身有一部份，原型上面有一部份。同样是给 子类的实例 使用的属性，在两个位置传递参数 new Person()传递一部份，new Student() 传递一部分</p>
<p>不是不可以，只是不够友好</p>
<h3 id="3-call-继承"><a href="#3-call-继承" class="headerlink" title="3. call 继承"></a>3. call 继承</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//父类</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sayHi</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;hello world&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">      call继承</span></span><br><span class="line"><span class="comment">      + 核心 利用call调用父类的构造函数</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line"><span class="comment">//子类</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Student</span>(<span class="params">gender, ...arg</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">gender</span> = gender;</span><br><span class="line">  <span class="comment">//this 只要你new 永远是实例对象</span></span><br><span class="line">  <span class="comment">//实现继承</span></span><br><span class="line">  <span class="title class_">Person</span>.<span class="title function_">call</span>(<span class="variable language_">this</span>, ...arg);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// function Student(gender, name, age) &#123;</span></span><br><span class="line"><span class="comment">//   this.gender = gender;</span></span><br><span class="line"><span class="comment">//   //this 只要你new 永远是实例对象</span></span><br><span class="line"><span class="comment">//   //实现继承</span></span><br><span class="line"><span class="comment">//   Person.call(this, name, age);</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="title class_">Student</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">play</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;没日没夜的玩&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">const</span> s = <span class="keyword">new</span> <span class="title class_">Student</span>(<span class="string">&#x27;男&#x27;</span>, <span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>);</span><br><span class="line"><span class="comment">// Person.call(s, &#x27;alex&#x27;, 18);</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(s);</span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">      构造函数 </span></span><br><span class="line"><span class="comment">        构造函数本身也是一个函数</span></span><br><span class="line"><span class="comment">        是函数就能直接调用，可以不和new连用</span></span><br><span class="line"><span class="comment">        只是没有new的话，就没有创建对象的能力</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line"><span class="comment">//把Person当作一个普通函数来调用，Person内的this-&gt;window</span></span><br><span class="line"><span class="comment">//Person函数体内的两个属性 加给了window</span></span><br><span class="line"><span class="comment">// Person(&#x27;haha&#x27;, 18);不报错</span></span><br><span class="line"><span class="comment">//既然Person能够当作普通函数来调用</span></span><br><span class="line"><span class="comment">//call来调用函数并且改变里面的this指向</span></span><br><span class="line"><span class="comment">// const obj = &#123; msg: &#x27;我是obj&#x27; &#125;;</span></span><br><span class="line"><span class="comment">// Person.call(obj, &#x27;tom&#x27;, 28);</span></span><br><span class="line"><span class="comment">// console.log(obj);</span></span><br></pre></td></tr></table></figure>

<p>核心:利用 call 调用父类的构造函数</p>
<p>优缺点:<br>优点:可以把继承来的属性直接出现在 子类的实例 身上，一个实例需要用的属性可以在同一个位置传递参数<br>缺点:只能继承 构造函数体内书写的内容， 构造函数 原型上的 不能继承</p>
<h3 id="4-组合继承"><a href="#4-组合继承" class="headerlink" title="4. 组合继承"></a>4. 组合继承</h3><p>原型继承和 call&#x2F;apply 继承 优缺点刚好互补<br>一种新的相对完美的继承方式就出来了，利用好这两种方式的优缺点</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//父类</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sayHi</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;hello world&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">      组合继承:</span></span><br><span class="line"><span class="comment">        核心:把 原型继承 和 call继承 合在一起</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line"><span class="comment">//子类</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Student</span>(<span class="params">gender, ...arg</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">gender</span> = gender;</span><br><span class="line">  <span class="comment">//实现call继承，</span></span><br><span class="line">  <span class="comment">//目的:把构造函数体内的属性都拿到</span></span><br><span class="line">  <span class="title class_">Person</span>.<span class="title function_">call</span>(<span class="variable language_">this</span>, ...arg);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//实现原型继承</span></span><br><span class="line"><span class="comment">//目的:拿到Person.prototype上的方法</span></span><br><span class="line"><span class="comment">//这里new Person()可以不用写，因为对象属性的访问机制</span></span><br><span class="line"><span class="comment">// Student.prototype = new Person(&#x27;jack&#x27;, 18);</span></span><br><span class="line"><span class="title class_">Student</span>.<span class="property"><span class="keyword">prototype</span></span> = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line"><span class="title class_">Student</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">play</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;没日没夜的玩&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">let</span> s = <span class="keyword">new</span> <span class="title class_">Student</span>(<span class="string">&#x27;男&#x27;</span>, <span class="string">&#x27;alex&#x27;</span>, <span class="number">88</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(s);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(s.<span class="property">name</span>, s.<span class="property">age</span>); <span class="comment">//alex 88</span></span><br></pre></td></tr></table></figure>

<h3 id="5-es6-继承"><a href="#5-es6-继承" class="headerlink" title="5. es6 继承"></a>5. es6 继承</h3><ol>
<li>使用 extends 关键字<br>class 子类 extends 父类{…}</li>
<li>在子类的 constructor 内书写<br>super()</li>
</ol>
<p>注意:必须两个条件同时书写，super 必须写在所有的 this 之前，父类如果是一个 es5 的构造函数，那么也可以正常继承</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//父类</span></span><br><span class="line"><span class="comment">// class Person &#123;</span></span><br><span class="line"><span class="comment">//   constructor(name, age) &#123;</span></span><br><span class="line"><span class="comment">//     this.name = name;</span></span><br><span class="line"><span class="comment">//     this.age = age;</span></span><br><span class="line"><span class="comment">//   &#125;</span></span><br><span class="line"><span class="comment">//   sayHi() &#123;</span></span><br><span class="line"><span class="comment">//     console.log(&#x27;hello world&#x27;);</span></span><br><span class="line"><span class="comment">//   &#125;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//es5的</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">sayHi</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;hello world&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">//子类</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Person</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">gender, name, age</span>) &#123;</span><br><span class="line">    <span class="comment">//super就类似于call调用父类构造函数</span></span><br><span class="line">    <span class="comment">//把name和age传递过去</span></span><br><span class="line">    <span class="variable language_">super</span>(name, age);</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">gender</span> = gender;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">play</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;没日没夜的玩&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> s = <span class="keyword">new</span> <span class="title class_">Student</span>(<span class="string">&#x27;男&#x27;</span>, <span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(s);</span><br></pre></td></tr></table></figure>

<h1 id="js的运行原理"><a href="#js的运行原理" class="headerlink" title="js的运行原理"></a>js的运行原理</h1><h2 id="V8如何把js运行起来"><a href="#V8如何把js运行起来" class="headerlink" title="V8如何把js运行起来"></a>V8如何把js运行起来</h2><h3 id="V8引擎原理"><a href="#V8引擎原理" class="headerlink" title="V8引擎原理"></a>V8引擎原理</h3><h4 id="js代码的执行"><a href="#js代码的执行" class="headerlink" title="js代码的执行"></a>js代码的执行</h4><p>高级语言写的代码最终都是通过计算机硬件（CPU）运行的，</p>
<p>但计算机不能直接识别js的代码，需要通过一定的转换，变成计算机能够识别的二进制机器码，计算机执行后才能看到实现的效果。</p>
<h5 id="什么是V8"><a href="#什么是V8" class="headerlink" title="什么是V8"></a>什么是V8</h5><p>V8是Google使用C++编写的开源高性能JS和WebAssmbly引擎，广泛应用于chrome和Node.js，能够跨平台，独立运行，还能嵌入任何C++应用程序中</p>
<h5 id="V8架构"><a href="#V8架构" class="headerlink" title="V8架构"></a>V8架构</h5><p><strong>Parse 解析</strong>(<a target="_blank" rel="noopener" href="https://v8.dev/blog/scanner">https://v8.dev/blog/scanner</a>)</p>
<ul>
<li>将js代码转化成AST（抽象语法树），如果函数没有调用，不会将函数转化成抽象树。</li>
</ul>
<p><strong>Ignition 解释器</strong>(<a target="_blank" rel="noopener" href="https://v8.dev/blog/ignition-interpreter">https://v8.dev/blog/ignition-interpreter</a>)</p>
<ul>
<li>将AST转换成bytecode（字节码）</li>
<li>帮助Turbo Fan收集信息</li>
<li>如果函数只调用一次，Ignition会执行bytecode</li>
</ul>
<p><strong>Turbo Fan 编译器</strong>(<a target="_blank" rel="noopener" href="https://v8.dev/blog/turbofan-jit">https://v8.dev/blog/turbofan-jit</a>)</p>
<ul>
<li>收集信息，优化代码的执行速度</li>
<li>反向优化，重新将机器码转化成字节码</li>
</ul>
<p>多次调用的函数在<strong>Turbo Fan</strong>中也叫<strong>热点函数</strong></p>
<p><strong>Garbage Collection 垃圾回收机制</strong></p>
<h2 id="js执行上下文GO-AO-VO"><a href="#js执行上下文GO-AO-VO" class="headerlink" title="js执行上下文GO AO VO"></a>js执行上下文GO AO VO</h2><h3 id="2-1-初始化全局对象"><a href="#2-1-初始化全局对象" class="headerlink" title="2.1 初始化全局对象"></a>2.1 初始化全局对象</h3><ul>
<li>在执行代码之前，js引擎会在堆内存中创建一个全局对象：Global Object（GO）</li>
<li>在浏览器中全局对象就是window，所以在执行所有代码之前window已经创建好了，该对象所有的作用域都能访问，里面会包含Date、Math、String</li>
</ul>
<h3 id="2-2-执行上下文"><a href="#2-2-执行上下文" class="headerlink" title="2.2 执行上下文"></a>2.2 执行上下文</h3><p>js引擎内部有一个执行上下文，它是用于执行代码的调用栈</p>
<p>GEC（全局执行上下文）被放入ESC（执行上下文）中包含两部分内容</p>
<ol>
<li>在代码执行之前，在parser转成AST的过程中，它会将全局定义的变量，函数放入到GO中，但是不会赋值，这个过程也被称为<strong>变量作用域的提升</strong></li>
<li>在代码执行过程中，对变量赋值或者执行其他的函数</li>
</ol>
<p>只要执行代码js就会创建一个执行上下文</p>
<h3 id="2-3-VO对象"><a href="#2-3-VO对象" class="headerlink" title="2.3 VO对象"></a>2.3 VO对象</h3><ul>
<li><p>每一个执行上下文关联一个对应的VO（variable Object）变量和函数都会被添加到VO对象中</p>
</li>
<li><p>对于全局代码而言我们的VO就是GO，但是函数有点特殊，它会优先把函数对象创建出来，创建的时候里面默认有name，length，arguments</p>
</li>
</ul>
<h5 id="补充：Function-length属性"><a href="#补充：Function-length属性" class="headerlink" title="补充：Function.length属性"></a>补充：Function.length属性</h5><p><strong><code>length</code></strong> 属性指明函数的<strong>形参个数</strong>。</p>
<p><code>length</code> 是函数对象的一个<strong>属性值</strong>，指该函数期望传入的参数数量，即形参的个数。</p>
<p>形参的数量不包括<strong>剩余参数（…args）</strong>个数，仅包括<strong>第一个具有默认值之前</strong>的参数个数。</p>
<p>与之对比的是，<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments/length"><code>arguments.length</code></a> 是函数被调用时实际传参的个数。</p>
<p>3.函数代码执行</p>
<p><strong>总结</strong>:</p>
<p>当我们去执行一段代码，不管是全局代码还是函数内部的代码，都会创建一个对应的执行上下文，如果执行的是全局代码，创建的VO就是GO，如果执行的是函数内部的代码，创建的VO就是AO</p>
<h2 id="全局代码如何执行"><a href="#全局代码如何执行" class="headerlink" title="全局代码如何执行"></a>全局代码如何执行</h2><h5 id="函数的-length-属性"><a href="#函数的-length-属性" class="headerlink" title="函数的 length 属性"></a>函数的 length 属性</h5><ol>
<li><strong>形参个数</strong></li>
</ol>
<ul>
<li>函数全部的形参没有默认值，则<strong>function</strong>的length就是形参的个数</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">fn1</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn2</span>(<span class="params">name</span>) &#123;&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn3</span>(<span class="params">name, age</span>) &#123;&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fn1.<span class="property">length</span>); <span class="comment">//0</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fn2.<span class="property">length</span>); <span class="comment">//1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fn3.<span class="property">length</span>); <span class="comment">//2</span></span><br></pre></td></tr></table></figure>

<ol start="2">
<li><strong>默认参数</strong></li>
</ol>
<ul>
<li>如果函数的形参有默认值，则<strong>function</strong> 的 <strong>length</strong>是<strong>第一个具有默认值之前</strong>的形参个数</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">fn1</span>(<span class="params">name</span>) &#123;&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn2</span>(<span class="params">name = <span class="string">&#x27;alex&#x27;</span></span>) &#123;&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn3</span>(<span class="params">name, age = <span class="number">22</span></span>) &#123;&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn4</span>(<span class="params">name, age = <span class="number">22</span>, gender</span>) &#123;&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn5</span>(<span class="params">name, age, gender = <span class="string">&#x27;男&#x27;</span></span>) &#123;&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">fn6</span>(<span class="params">name = <span class="string">&#x27;alex&#x27;</span>, age, gender</span>) &#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fn1.<span class="property">length</span>); <span class="comment">//1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fn2.<span class="property">length</span>); <span class="comment">//0</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fn3.<span class="property">length</span>); <span class="comment">//1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fn4.<span class="property">length</span>); <span class="comment">//1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fn5.<span class="property">length</span>); <span class="comment">//2</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fn6.<span class="property">length</span>); <span class="comment">//0</span></span><br></pre></td></tr></table></figure>

<ol start="3">
<li><strong>剩余参数</strong></li>
</ol>
<ul>
<li>剩余参数不计入函数的长度中</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">fn1</span>(<span class="params">name, ...args</span>) &#123;&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(fn1.<span class="property">length</span>); <span class="comment">//1</span></span><br></pre></td></tr></table></figure>

<p><strong>面试题：</strong><code>123[&#39;toString&#39;].length+123=124</code></p>
<h3 id="3-函数代码执行"><a href="#3-函数代码执行" class="headerlink" title="3.函数代码执行"></a>3.函数代码执行</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> message = <span class="string">&#x27;Global Message&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">num</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> message = <span class="string">&#x27;Foo Message&#x27;</span>;</span><br><span class="line">  <span class="keyword">var</span> age = <span class="number">18</span>;</span><br><span class="line">  <span class="keyword">var</span> height = <span class="number">1.88</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;foo function&#x27;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">foo</span>(<span class="number">123</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> num1 = <span class="number">10</span>;</span><br><span class="line"><span class="keyword">var</span> num2 = <span class="number">20</span>;</span><br><span class="line"><span class="keyword">var</span> result = num1 + num2;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(result);</span><br></pre></td></tr></table></figure>

<ul>
<li>因为每个执行上下文都会关联一个 <strong>VO</strong>，那么函数执行的时候也要关联对应的 VO，<strong>函数</strong>的 VO 叫做 <strong>AO 对象</strong>(Activation Object),这个 AO 对象会作为执行上下文的 VO 来存放函数中的私有变量</li>
</ul>
<p><strong>易错点</strong>：创建函数的时候就会创建一个 AO 对象，完全不对，这两者没有任何关系，<strong>AO 是函数调用的时候才有的</strong></p>
<h3 id="4-函数代码多次执行"><a href="#4-函数代码多次执行" class="headerlink" title="4.函数代码多次执行"></a>4.函数代码多次执行</h3><p>重新创建对应的 EC，关联对应的 VO，创建对应的 AO，执行完以后弹出栈，如果我们不做任何其他的操作，销毁 AO。</p>
<h3 id="5-函数代码互相调用"><a href="#5-函数代码互相调用" class="headerlink" title="5. 函数代码互相调用"></a>5. 函数代码互相调用</h3><p>一样的操作，只不过是创建对应的 EC，关联对应的 VO，创建对应的 AO，执行完以后弹出栈，如果我们不做任何其他的操作，销毁 AO</p>
<h2 id="函数执行过程"><a href="#函数执行过程" class="headerlink" title="函数执行过程"></a>函数执行过程</h2><h2 id="作用域和作用域链"><a href="#作用域和作用域链" class="headerlink" title="作用域和作用域链"></a>作用域和作用域链</h2><h4 id="6-1-全局变量的查找顺序"><a href="#6-1-全局变量的查找顺序" class="headerlink" title="6.1 全局变量的查找顺序"></a>6.1 全局变量的查找顺序</h4><p>去自己的 VO 的查找</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(message);</span><br><span class="line"><span class="keyword">var</span> message = <span class="string">&#x27;Global message&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(message);</span><br></pre></td></tr></table></figure>

<p>作用域提升:对后面定义的变量做一个提前的访问。</p>
<h4 id="6-2-函数变量的查找顺序"><a href="#6-2-函数变量的查找顺序" class="headerlink" title="6.2 函数变量的查找顺序"></a>6.2 函数变量的查找顺序</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(message);</span><br><span class="line"><span class="keyword">var</span> message = <span class="string">&#x27;Global message&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> message = <span class="string">&#x27;foo message&#x27;</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(message);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">foo</span>();</span><br></pre></td></tr></table></figure>

<h5 id="作用域链"><a href="#作用域链" class="headerlink" title="作用域链"></a>作用域链</h5><p>作用域链它是一个对象列表，用于变量标识符的求值<br>当进入一个执行上下文的时候，作用域链被创建，并且根据代码类型，添加一系列的对象。</p>
<p>如果是全局，作用域链就只有一个 GO；如果是函数，当函数被创建的时候，而不是调用，它的作用域链就被确定了。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(message);</span><br><span class="line"><span class="keyword">var</span> message = <span class="string">&#x27;Global message&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(message);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">foo</span>();</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;obj&#x27;</span>,</span><br><span class="line">  <span class="attr">messsage</span>: <span class="string">&#x27;12312&#x27;</span>,</span><br><span class="line">  <span class="attr">bar</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> message = <span class="string">&#x27;obj内的bar&#x27;</span>;</span><br><span class="line">    <span class="title function_">foo</span>();</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">obj.<span class="title function_">bar</span>();</span><br><span class="line">obj[<span class="string">&#x27;bar&#x27;</span>]();</span><br></pre></td></tr></table></figure>

<h4 id="6-3-多层嵌套的查找顺序"><a href="#6-3-多层嵌套的查找顺序" class="headerlink" title="6.3 多层嵌套的查找顺序"></a>6.3 多层嵌套的查找顺序</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(message);</span><br><span class="line"><span class="keyword">var</span> message = <span class="string">&#x27;Global message&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> name = <span class="string">&#x27;foo&#x27;</span>;</span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">bar</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(name);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> bar;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> bar = <span class="title function_">foo</span>();</span><br><span class="line"><span class="title function_">bar</span>();</span><br></pre></td></tr></table></figure>

<h4 id="6-4-几道经典的面试题"><a href="#6-4-几道经典的面试题" class="headerlink" title="6.4 几道经典的面试题"></a>6.4 几道经典的面试题</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> n = <span class="number">100</span>;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  n = <span class="number">200</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(n); <span class="comment">//200</span></span><br></pre></td></tr></table></figure>

<p>foo 自身的 AO 里面没有 n,去找<code>[[Scopes]]</code>,只有一个 GO，修改成 200</p>
<hr>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> n = <span class="number">100</span>;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(n);</span><br><span class="line">  <span class="keyword">var</span> n = <span class="number">200</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(n);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>();</span><br></pre></td></tr></table></figure>

<hr>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> n = <span class="number">100</span>;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo1</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(n);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo2</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> n = <span class="number">200</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(n);</span><br><span class="line">  <span class="title function_">foo1</span>();</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo2</span>();</span><br></pre></td></tr></table></figure>

<hr>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> n = <span class="number">100</span>;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(n);</span><br><span class="line">  <span class="keyword">return</span>;</span><br><span class="line">  <span class="keyword">var</span> n = <span class="number">200</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>();</span><br></pre></td></tr></table></figure>

<hr>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//开发之中很可能出现的错误❌写法</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  msg = <span class="string">&#x27;hello world&#x27;</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(msg);</span><br></pre></td></tr></table></figure>

<hr>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> a = (b = <span class="number">200</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a); <span class="comment">//报错</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(b);</span><br></pre></td></tr></table></figure>

<h2 id="javascript-的内存管理"><a href="#javascript-的内存管理" class="headerlink" title="javascript 的内存管理"></a>javascript 的内存管理</h2><h3 id="1-1-认识内存管理"><a href="#1-1-认识内存管理" class="headerlink" title="1.1 认识内存管理"></a>1.1 认识内存管理</h3><p>不管是什么样的编程语言，在代码的执行过程中都是需要给他<strong>分配内存</strong>的，不同的是有些编程语言需要我们自己手动管理内存，有些编程语言可以自动管理内存。</p>
<p>不管是什么方式来管理内存，内存的管理都会有如下的<strong>生命周期</strong>:</p>
<ol>
<li>分配申请你需要的内存(申请)</li>
<li>使用分配的内存</li>
<li>不需要使用时，对其进行释放</li>
</ol>
<h3 id="1-2-js-的内存管理"><a href="#1-2-js-的内存管理" class="headerlink" title="1.2 js 的内存管理"></a>1.2 js 的内存管理</h3><ul>
<li><p>对于原始数据类型，直接在栈里面分配</p>
</li>
<li><p>对于复杂数据类型，在堆里面分配，并将这块空间的指针返回给你的变量名引用</p>
</li>
</ul>
<h2 id="2-垃圾回收机制算法"><a href="#2-垃圾回收机制算法" class="headerlink" title="2. 垃圾回收机制算法"></a>2. 垃圾回收机制算法</h2><h3 id="2-1-js-的垃圾回收（Garbage-Collection）"><a href="#2-1-js-的垃圾回收（Garbage-Collection）" class="headerlink" title="2.1 js 的垃圾回收（Garbage Collection）"></a>2.1 js 的垃圾回收（Garbage Collection）</h3><p><strong>原因：</strong>因为内存的大小是有限的，所以当内存里面的对象不再需要时，我们就要对他进行释放，以便腾出空间。<br>Garbage Collection，简称 GC。</p>
<h3 id="2-2引用计数（Reference-counting）"><a href="#2-2引用计数（Reference-counting）" class="headerlink" title="2.2引用计数（Reference counting）"></a>2.2引用计数（Reference counting）</h3><ul>
<li>当一个对象<strong>有一个引用</strong>指向他时，这个对象的<strong>引用就+1</strong>;</li>
<li>当一个对象的引用为 <strong>0</strong> 时，这个对象就可以被<strong>销毁</strong>掉</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> user = &#123; <span class="attr">username</span>: <span class="string">&#x27;alex chen&#x27;</span> &#125;; <span class="comment">//对象被引用 计数+1</span></span><br><span class="line"><span class="keyword">let</span> user2 = user; <span class="comment">//对象又被引用 计数+1</span></span><br><span class="line">user = <span class="literal">null</span>; <span class="comment">//变量不再引用对象 计数-1</span></span><br><span class="line">user2 = <span class="literal">null</span>; <span class="comment">//变量不再引用对象 计数-1</span></span><br><span class="line"><span class="comment">//此时 这个对象 计数为0 可以销毁</span></span><br></pre></td></tr></table></figure>

<p>这个方法虽然看起来合理，但是存在明显的漏洞，那就是<strong>循环引用</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> boy = &#123;&#125;;</span><br><span class="line"><span class="keyword">let</span> girl = &#123;&#125;;</span><br><span class="line">boy.<span class="property">girlfriend</span> = girl;</span><br><span class="line">girl.<span class="property">boyfriend</span> = boy;</span><br><span class="line">boy = <span class="literal">null</span>;</span><br><span class="line">girl = <span class="literal">null</span>;</span><br><span class="line"><span class="comment">//想要清除</span></span><br><span class="line">boy.<span class="property">girlfriend</span> = <span class="literal">null</span>;</span><br><span class="line">girl.<span class="property">boyfriend</span> = <span class="literal">null</span>;</span><br></pre></td></tr></table></figure>

<h3 id="2-3-标记-清除-mark-Sweep"><a href="#2-3-标记-清除-mark-Sweep" class="headerlink" title="2.3 标记-清除(mark-Sweep)"></a>2.3 标记-清除(mark-Sweep)</h3><p>核心思路是可达性,这个算法是设置一个根对象(Root Object),垃圾回收器会定期从根开始，找到所有从根开始引用的对象，对于那些没有的对象，认为是后续不再用的，就给他销毁，这个算法可以很好的解决循环引用的问题。</p>
<h3 id="2-4-常见的其他-GC-算法"><a href="#2-4-常见的其他-GC-算法" class="headerlink" title="2.4 常见的其他 GC 算法"></a>2.4 常见的其他 GC 算法</h3><ol>
<li>标记整理(Mark-Compact)</li>
<li>分代收集(Generational collection)<br>对象被划分成两组:’新的’和’旧的’<br>减少对老旧对象的扫描频率</li>
<li>增量收集(Incremental collection) 大的-&gt;很多个小的</li>
<li>闲时收集(idle-time collection)</li>
</ol>
<h3 id="2-5-V8-引擎详细内存图"><a href="#2-5-V8-引擎详细内存图" class="headerlink" title="2.5 V8 引擎详细内存图"></a>2.5 V8 引擎详细内存图</h3><p><img src="https://markdown-1317399397.cos.ap-guangzhou.myqcloud.com/V8%E7%9A%84%E8%AF%A6%E7%BB%86%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86%E5%9B%BE.png"></p>
<h2 id="3-闭包"><a href="#3-闭包" class="headerlink" title="3. 闭包"></a>3. 闭包</h2><h3 id="3-1-js-的函数式编程"><a href="#3-1-js-的函数式编程" class="headerlink" title="3.1 js 的函数式编程"></a>3.1 js 的函数式编程</h3><p>js 中函数非常重要，而且是一等公民。函数可以作为另一个函数的参数，也可以作为函数的返回值。<br>vue:optionsAPI-&gt;compositionAPI-&gt;函数 hook<br>react:class-&gt;function-&gt;hooks</p>
<h3 id="3-2-闭包的概念"><a href="#3-2-闭包的概念" class="headerlink" title="3.2 闭包的概念"></a>3.2 闭包的概念</h3><p>在计算机科学:Closure,又叫词法闭包(Lexical Closure)或者函数闭包,是在<strong>头等函数</strong>的编程语言中，实现词法绑定的一种技术，闭包在实现上是一个结构体，他存储了一个函数和一个关联的环境。闭包跟函数最大的区别在于，当捕获闭包的时候，他的<strong>自由变量</strong>会在被捕捉时确定。这样即使脱离了上下文，他也能照常运行。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> name = <span class="string">&#x27;alex&#x27;</span>;</span><br><span class="line"><span class="keyword">var</span> age = <span class="number">18</span>;</span><br><span class="line"><span class="keyword">var</span> info = <span class="string">&#x27;唱跳rap&#x27;</span>;</span><br><span class="line"><span class="comment">//有闭包</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> msg = <span class="string">&#x27;hello world&#x27;</span>;</span><br><span class="line">  <span class="comment">//js底层帮你做了一件事--闭包</span></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(msg, name, age, info);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//没有闭包</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">bar</span>(<span class="params">name, age, info, address, hobby, height</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> msg = <span class="string">&#x27;hello world&#x27;</span>;</span><br><span class="line">  <span class="comment">//js底层帮你做了一件事--闭包</span></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(msg, name, age, info);</span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">baz</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(msg, name, age, info);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//这里 既有外面的变量 也有我自己的</span></span><br><span class="line"><span class="comment">//全部混淆在一起 --- 希望一个函数只做一件事</span></span><br><span class="line"><span class="title function_">bar</span>(name, age, info, address, hobby, height);</span><br><span class="line"><span class="title function_">foo</span>();</span><br><span class="line"><span class="comment">//作用域链的存在，就是为了方便你去外面找东西，也就是为了闭包</span></span><br></pre></td></tr></table></figure>

<p>私人:<br>广义上来说，js 中的函数都是闭包。<br>狭义说：js 中的函数，访问了外层作用域的变量，才叫做闭包。</p>
<h2 id="4-闭包的形成过程"><a href="#4-闭包的形成过程" class="headerlink" title="4. 闭包的形成过程"></a>4. 闭包的形成过程</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//新手</span></span><br><span class="line"><span class="comment">// function adder(num,count) &#123;</span></span><br><span class="line"><span class="comment">//   return num + count;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// adder(100,5); //105</span></span><br><span class="line"><span class="comment">// adder(5,5); //10</span></span><br><span class="line"><span class="comment">// adder(55,5); //60</span></span><br><span class="line"><span class="comment">// //我要 后三次调用+8</span></span><br><span class="line"><span class="comment">// adder(22,8)</span></span><br><span class="line"><span class="comment">// adder(12,8)</span></span><br><span class="line"><span class="comment">// adder(2,8)</span></span><br><span class="line"><span class="comment">//nest.js 全栈</span></span><br><span class="line"><span class="comment">//老手</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">createAdder</span>(<span class="params">count</span>) &#123;</span><br><span class="line">  <span class="comment">// function adder(num) &#123;</span></span><br><span class="line">  <span class="comment">//   return count + num;</span></span><br><span class="line">  <span class="comment">// &#125;</span></span><br><span class="line">  <span class="comment">// return adder;</span></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">num</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> count + num;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// let createAdder1 = count=&gt; num =&gt; count + num;</span></span><br><span class="line"><span class="comment">// let adder4= createAdder1(4)</span></span><br><span class="line"><span class="comment">// let res = adder4(16)</span></span><br><span class="line"><span class="comment">// console.log(res);</span></span><br><span class="line"><span class="keyword">let</span> adder5 = <span class="title function_">createAdder</span>(<span class="number">5</span>);</span><br><span class="line"><span class="title function_">adder5</span>(<span class="number">15</span>); <span class="comment">//20</span></span><br><span class="line"><span class="title function_">adder5</span>(<span class="number">25</span>);</span><br><span class="line"><span class="title function_">adder5</span>(<span class="number">35</span>);</span><br><span class="line"><span class="keyword">let</span> adder8 = <span class="title function_">createAdder</span>(<span class="number">8</span>);</span><br><span class="line"><span class="title function_">adder8</span>(<span class="number">2</span>);</span><br><span class="line"><span class="title function_">adder8</span>(<span class="number">12</span>);</span><br><span class="line"><span class="title function_">adder8</span>(<span class="number">22</span>);</span><br></pre></td></tr></table></figure>

<p>看图</p>
<h2 id="5-闭包的内存泄漏"><a href="#5-闭包的内存泄漏" class="headerlink" title="5. 闭包的内存泄漏"></a>5. 闭包的内存泄漏</h2><p>我们图里 adder5 adder8 以及对应的 AO 对象，存在引用而且也是根可达的所以即使后续不再使用也不会释放。我们经常说的闭包的内存泄漏，其实就是这些引用链上的对象无法释放。</p>
<h3 id="5-1-如何释放"><a href="#5-1-如何释放" class="headerlink" title="5.1 如何释放"></a>5.1 如何释放</h3><p>比如说我们要释放 adder5,<code>adder5=null</code></p>
<h3 id="5-2-内存泄漏的测试"><a href="#5-2-内存泄漏的测试" class="headerlink" title="5.2 内存泄漏的测试"></a>5.2 内存泄漏的测试</h3><p><img src="https://markdown-1317399397.cos.ap-guangzhou.myqcloud.com/2023-05-16-11-56-33.png" alt="2023-05-16-11-56-33.png"></p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">class</span>=<span class="string">&quot;create&quot;</span>&gt;</span>创建很多对象<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">class</span>=<span class="string">&quot;destory&quot;</span>&gt;</span>销毁很多对象<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">function</span> <span class="title function_">createArray</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="comment">//4 1024 -&gt;4kb *1024 -&gt;4M</span></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">var</span> arr = <span class="keyword">new</span> <span class="title class_">Array</span>(<span class="number">1024</span> * <span class="number">1024</span>).<span class="title function_">fill</span>(<span class="number">1</span>);</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">function</span> <span class="title function_">test</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="variable language_">console</span>.<span class="title function_">log</span>(arr);</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">return</span> test;</span></span><br><span class="line"><span class="language-javascript">  &#125;</span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">var</span> totalArr = [];</span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">let</span> createBtn = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;.create&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">let</span> destoryBtn = <span class="variable language_">document</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;.destory&#x27;</span>);</span></span><br><span class="line"><span class="language-javascript">  createBtn.<span class="property">onclick</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="number">100</span>; i++) &#123;</span></span><br><span class="line"><span class="language-javascript">      totalArr.<span class="title function_">push</span>(<span class="title function_">createArray</span>());</span></span><br><span class="line"><span class="language-javascript">    &#125;</span></span><br><span class="line"><span class="language-javascript">    <span class="variable language_">console</span>.<span class="title function_">log</span>(totalArr.<span class="property">length</span>);</span></span><br><span class="line"><span class="language-javascript">  &#125;;</span></span><br><span class="line"><span class="language-javascript">  destoryBtn.<span class="property">onclick</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">    totalArr = [];</span></span><br><span class="line"><span class="language-javascript">  &#125;;</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h3 id="5-3-AO-不使用的属性优化"><a href="#5-3-AO-不使用的属性优化" class="headerlink" title="5.3 AO 不使用的属性优化"></a>5.3 AO 不使用的属性优化</h3><p>不被销毁的 AO 对象，里面所有的属性都一直保留吗？<br><strong>结论</strong>：不使用的不会保留–浏览器自己的优化</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> name = <span class="string">&#x27;foo&#x27;</span>;</span><br><span class="line">  <span class="keyword">var</span> age = <span class="number">18</span>;</span><br><span class="line">  <span class="keyword">var</span> height = <span class="number">1.88</span>;</span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">bar</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">debugger</span>;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(name);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> bar;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> fn = <span class="title function_">foo</span>();</span><br><span class="line"><span class="title function_">fn</span>();</span><br></pre></td></tr></table></figure>

<h2 id="函数的增强知识"><a href="#函数的增强知识" class="headerlink" title="函数的增强知识"></a>函数的增强知识</h2><h3 id="1-1-函数的属性和-arguments"><a href="#1-1-函数的属性和-arguments" class="headerlink" title="1.1 函数的属性和 arguments"></a>1.1 函数的属性和 arguments</h3><h4 id="1-1-1-函数的属性"><a href="#1-1-1-函数的属性" class="headerlink" title="1.1.1 函数的属性"></a>1.1.1 函数的属性</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">a, b, c</span>) &#123;&#125;</span><br><span class="line"><span class="keyword">let</span> obj = &#123;&#125;;</span><br><span class="line">obj.<span class="property">address</span> = <span class="string">&#x27;天河&#x27;</span>;</span><br><span class="line"><span class="comment">//自定义属性</span></span><br><span class="line">foo.<span class="property">msg</span> = <span class="string">&#x27;hello foo&#x27;</span>;</span><br></pre></td></tr></table></figure>

<ul>
<li>除了自定义属性以外，函数对象中已经有一些自己的属性。</li>
</ul>
<ol>
<li><strong>name</strong>:函数的名字</li>
<li><strong>length</strong>:第一个具有默认值参数之前的参数的个数</li>
</ol>
<h4 id="1-1-2-Arguments类数组对象"><a href="#1-1-2-Arguments类数组对象" class="headerlink" title="1.1.2 Arguments类数组对象"></a>1.1.2 Arguments类数组对象</h4><p>概念：**<code>arguments</code>** 是一个对应于传递给函数的参数的类数组对象。</p>
<ul>
<li>array-like 对象不是一个真正的数组，它类似于<code>Array</code>，但除了 length 属性和索引元素之外没有任何<code>Array</code>属性。如pop、filter、map等方法</li>
<li>在开发中，如果需要对 <strong><code>arguments</code></strong> 进行操作的时候要用到数组的一些特性，那我们就需要把他转成数组。</li>
</ul>
<p>转成数组的三种方法</p>
<ol>
<li><strong>遍历添加</strong></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">arguments</span>);</span><br><span class="line">  <span class="keyword">let</span> newArr = [];</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">const</span> arg <span class="keyword">of</span> <span class="variable language_">arguments</span>) &#123;</span><br><span class="line">    newArr.<span class="title function_">push</span>(arg);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(newArr);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>(<span class="number">10</span>, <span class="number">20</span>, <span class="number">12</span>, <span class="number">11</span>, <span class="number">333</span>);</span><br></pre></td></tr></table></figure>

<ol start="2">
<li><strong>es6 的方法</strong></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> newArr = [...<span class="variable language_">arguments</span>];</span><br><span class="line"><span class="keyword">let</span> newArr1 = <span class="title class_">Array</span>.<span class="title function_">from</span>(<span class="variable language_">arguments</span>);</span><br></pre></td></tr></table></figure>

<ol start="3">
<li><strong>slice+apply</strong></li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//回顾slice</span></span><br><span class="line"><span class="keyword">let</span> arr = [<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>];</span><br><span class="line"><span class="comment">//浅拷贝，引用赋值</span></span><br><span class="line"><span class="keyword">let</span> bar = arr.<span class="title function_">slice</span>(); <span class="comment">//this-&gt;arr</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//对象方法的调用</span></span><br><span class="line"><span class="comment">// obj.foo() //this-&gt;obj</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr, bar);</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">arguments</span>);</span><br><span class="line">  <span class="comment">//把arguments拷贝一份</span></span><br><span class="line">  <span class="comment">// slice.apply(&#123;1,2,3,,3213&#125;);</span></span><br><span class="line">  <span class="comment">// slice.apply(arguments);</span></span><br><span class="line">  <span class="keyword">let</span> newArr = <span class="title class_">Array</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">slice</span>.<span class="title function_">apply</span>(<span class="variable language_">arguments</span>);</span><br><span class="line">  <span class="keyword">let</span> newArr1 = [].<span class="property">slice</span>.<span class="title function_">apply</span>(<span class="variable language_">arguments</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//找方法把arguemnts转成数组</span></span><br><span class="line"><span class="comment">//slice返回一个数组给你</span></span><br><span class="line"><span class="comment">//找slice</span></span><br><span class="line"><span class="title function_">foo</span>(<span class="number">10</span>, <span class="number">20</span>, <span class="number">12</span>, <span class="number">11</span>, <span class="number">333</span>);</span><br></pre></td></tr></table></figure>

<h5 id="箭头函数的-arguments"><a href="#箭头函数的-arguments" class="headerlink" title="箭头函数的 arguments"></a>箭头函数的 <code>arguments</code></h5><ul>
<li>箭头函数中没有<code>arguments</code></li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="comment">//拿到的是外层作用域的arguments</span></span><br><span class="line">  <span class="keyword">let</span> <span class="title function_">bar</span> = (<span class="params"></span>) =&gt; &#123;</span><br><span class="line">    <span class="comment">//自己没有arguements</span></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">arguments</span>);</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="title function_">bar</span>();</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>(<span class="number">11</span>, <span class="number">22</span>);</span><br></pre></td></tr></table></figure>

<h5 id="ES6的Rest-parameters（剩余参数）"><a href="#ES6的Rest-parameters（剩余参数）" class="headerlink" title="ES6的Rest parameters（剩余参数）"></a>ES6的Rest parameters（剩余参数）</h5><p><strong>概念</strong>:将不定量的参数放入一个数组中</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">num1, num2, ...otherNums</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(otherNums);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>);</span><br></pre></td></tr></table></figure>

<p><strong>剩余参数和 <code>arguments</code> 区别</strong></p>
<ol>
<li>剩余参数是一个真正的数组，<code>arguments</code> 是一个类数组对象</li>
<li>剩余参数只包括没有对应形参的实参，<code>arguments</code> 包括所有的实参。</li>
<li><code>arguments</code>对象还有一些附加的属性（如callee属性）</li>
</ol>
<p><strong>注意</strong>：剩余参数只能写在最后面</p>
<h3 id="1-2-纯函数的理解和应用"><a href="#1-2-纯函数的理解和应用" class="headerlink" title="1.2 纯函数的理解和应用"></a>1.2 纯函数的理解和应用</h3><h4 id="1-2-1-纯函数的理解"><a href="#1-2-1-纯函数的理解" class="headerlink" title="1.2.1 纯函数的理解"></a>1.2.1 纯函数的理解</h4><p>在程序设计中，若一个函数符合以下条件，那么这个函数被称为<strong>纯函数</strong>。</p>
<ol>
<li>此函数在<strong>相同的输入</strong>时，需产生<strong>相同的输出</strong>。</li>
<li>函数的<strong>输出和输入</strong>值和<strong>其他的隐藏信息</strong>或者<strong>外部设备状态无关</strong>。</li>
<li>该函数不能有<strong>语义</strong>上可观察的<strong>函数副作用</strong>。</li>
</ol>
<p>私人:</p>
<ol>
<li>确定的输入，一定产生确定的输出</li>
<li>函数执行的过程中，不能产生副作用</li>
</ol>
<p><strong>计算机中的副作用</strong></p>
<ul>
<li>概念：在执行一个函数的时候，除了返回对应的值。还对调用函数产生了附加的影响，比如修改了全局变量，修改了参数，修改了外部的存储。</li>
</ul>
<p>判断以下函数是不是纯函数</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">sum</span>(<span class="params">a, b</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> a + b;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">printInfo</span>(<span class="params">info</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(info.<span class="property">name</span>, info.<span class="property">age</span>, info.<span class="property">msg</span>);</span><br><span class="line">  <span class="comment">//下面这句话让函数不再是纯函数</span></span><br><span class="line">  <span class="comment">// info.flag = &#x27;打印结束 哈哈哈&#x27;;</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">99</span>,</span><br><span class="line">  <span class="attr">msg</span>: <span class="string">&#x27;哈哈哈哈&#x27;</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="title function_">printInfo</span>(obj);</span><br><span class="line"></span><br><span class="line"><span class="comment">// if (obj.flag) &#123;</span></span><br><span class="line"><span class="comment">//   xxx;</span></span><br><span class="line"><span class="comment">// &#125; else &#123;</span></span><br><span class="line"><span class="comment">//   xxx;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br></pre></td></tr></table></figure>

<p><strong>例子</strong></p>
<ul>
<li>slice:截取数组，不会对原数组进行任何操作，而是返回一个新数组给你。是纯函数</li>
<li>splice:截取数组，返回一个新数组给你，就是已经改变的原数组。不是纯函数</li>
</ul>
<h4 id="1-2-2-纯函数的优势"><a href="#1-2-2-纯函数的优势" class="headerlink" title="1.2.2 纯函数的优势"></a>1.2.2 纯函数的优势</h4><ul>
<li>安心的编写 安心的使用</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> counter = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">add</span>(<span class="params">num</span>) &#123;</span><br><span class="line">  <span class="comment">//不能，需要关注外部的counter的变化</span></span><br><span class="line">  <span class="comment">// return num+counter</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">//可以随便用，你外部的counter哪怕变成一个对象/数组 都和我没关</span></span><br><span class="line">  <span class="keyword">return</span> num;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="1-3-柯里化的理解和应用"><a href="#1-3-柯里化的理解和应用" class="headerlink" title="1.3 柯里化的理解和应用"></a>1.3 柯里化的理解和应用</h3><h4 id="1-3-1-柯里化的理解"><a href="#1-3-1-柯里化的理解" class="headerlink" title="1.3.1 柯里化的理解"></a>1.3.1 柯里化的理解</h4><p><strong>概念：</strong>在计算机科学中，柯里化（Currying）是把接收<strong>多个参数的函数</strong>变换成接受一个<strong>单一参数(最初函数的第一个参数)的函数</strong>，并且返回<strong>接收余下的参数且返回结果的新函数</strong>的技术。</p>
<p><code>f(a,b,c)</code> 转成<code>f(a)(b)(c)</code></p>
<p><strong>注意：</strong>柯里化<strong>不会调用函数</strong>，只是对函数进行<strong>转化</strong>。</p>
<h4 id="1-3-2-柯里化函数变换"><a href="#1-3-2-柯里化函数变换" class="headerlink" title="1.3.2 柯里化函数变换"></a>1.3.2 柯里化函数变换</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo1</span>(<span class="params">x, y, z</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(x + y + z);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo1</span>(<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>);</span><br><span class="line"><span class="comment">// foo1(10)(20)(30)</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo2</span>(<span class="params">x</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">y</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">z</span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(x + y + z);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo2</span>(<span class="number">10</span>)(<span class="number">20</span>)(<span class="number">30</span>);</span><br><span class="line"><span class="comment">//箭头函数</span></span><br><span class="line"><span class="comment">// function foo3(x) &#123;</span></span><br><span class="line"><span class="comment">//   return (y) =&gt; &#123;</span></span><br><span class="line"><span class="comment">//     return (z) =&gt; &#123;</span></span><br><span class="line"><span class="comment">//       console.log(x + y + z);</span></span><br><span class="line"><span class="comment">//     &#125;;</span></span><br><span class="line"><span class="comment">//   &#125;;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="keyword">let</span> <span class="title function_">foo3</span> = (<span class="params">x</span>) =&gt; <span class="function">(<span class="params">y</span>) =&gt;</span> <span class="function">(<span class="params">z</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(x + y + z);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="title function_">foo3</span>(<span class="number">10</span>)(<span class="number">20</span>)(<span class="number">30</span>);</span><br></pre></td></tr></table></figure>

<h4 id="1-3-3-柯里化函数优势"><a href="#1-3-3-柯里化函数优势" class="headerlink" title="1.3.3 柯里化函数优势"></a>1.3.3 柯里化函数优势</h4><ol>
<li>函数的<strong>职责单一</strong> </li>
<li>函数的<strong>参数复用</strong></li>
</ol>
<h4 id="1-3-4-柯里化函数练习"><a href="#1-3-4-柯里化函数练习" class="headerlink" title="1.3.4 柯里化函数练习"></a>1.3.4 柯里化函数练习</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//打印一些日志</span></span><br><span class="line"><span class="comment">//日志的时间  日志的类型:info/debug/feature  具体的信息</span></span><br><span class="line"><span class="comment">// //没有柯里化</span></span><br><span class="line"><span class="comment">// function logInfo(date, type, msg) &#123;</span></span><br><span class="line"><span class="comment">//   console.log(`时间$&#123;date&#125;-类型$&#123;type&#125;-内容$&#123;msg&#125;`);</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// //打印日志</span></span><br><span class="line"><span class="comment">// logInfo(&#x27;2023-05-16&#x27;, &#x27;debug&#x27;, &#x27;修复样式bug&#x27;);</span></span><br><span class="line"><span class="comment">// //又修复了一个bug</span></span><br><span class="line"><span class="comment">// logInfo(&#x27;2023-05-16&#x27;, &#x27;debug&#x27;, &#x27;修复了接口的bug&#x27;);</span></span><br><span class="line"><span class="comment">//柯里化</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">logInfo</span>(<span class="params">date</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">type</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">msg</span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`时间<span class="subst">$&#123;date&#125;</span>-类型<span class="subst">$&#123;type&#125;</span>-内容<span class="subst">$&#123;msg&#125;</span>`</span>);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//                                      logInfo(时间)(类型)(内容)</span></span><br><span class="line"><span class="keyword">var</span> logToday = <span class="title function_">logInfo</span>(<span class="string">&#x27;2023-05-16&#x27;</span>); <span class="comment">//logInfo(时间)()()</span></span><br><span class="line"><span class="comment">//定义debug的日志</span></span><br><span class="line"><span class="keyword">var</span> logTodayDebug = <span class="title function_">logToday</span>(<span class="string">&#x27;debug&#x27;</span>); <span class="comment">//logInfo(时间)(类型)()</span></span><br><span class="line"><span class="comment">//定义feature的日志</span></span><br><span class="line"><span class="keyword">var</span> logTodayFeature = <span class="title function_">logToday</span>(<span class="string">&#x27;feature&#x27;</span>); <span class="comment">//logInfo(时间)(类型)()</span></span><br><span class="line"><span class="keyword">var</span> logTodayInfo = <span class="title function_">logToday</span>(<span class="string">&#x27;info&#x27;</span>); <span class="comment">//logInfo(时间)(类型)()</span></span><br><span class="line"><span class="comment">//今天 修改 bug  唯一变化 内容</span></span><br><span class="line"><span class="title function_">logTodayDebug</span>(<span class="string">&#x27;修复按钮点击&#x27;</span>);</span><br><span class="line"><span class="title function_">logTodayDebug</span>(<span class="string">&#x27;修复接口&#x27;</span>);</span><br><span class="line"><span class="title function_">logTodayDebug</span>(<span class="string">&#x27;修复排序&#x27;</span>);</span><br><span class="line"><span class="title function_">logTodayFeature</span>(<span class="string">&#x27;新增过滤&#x27;</span>);</span><br><span class="line"><span class="title function_">logTodayFeature</span>(<span class="string">&#x27;新增统计功能&#x27;</span>);</span><br></pre></td></tr></table></figure>

<h4 id="1-3-5-自动柯里化函数"><a href="#1-3-5-自动柯里化函数" class="headerlink" title="1.3.5 自动柯里化函数"></a>1.3.5 自动柯里化函数</h4><p>如何定义一个函数可以将多个参数的普通函数转成柯里化的函数</p>
<h3 id="1-4-组合函数的理解和应用"><a href="#1-4-组合函数的理解和应用" class="headerlink" title="1.4 组合函数的理解和应用"></a>1.4 组合函数的理解和应用</h3><h4 id="1-4-1-组合函数概念的理解"><a href="#1-4-1-组合函数概念的理解" class="headerlink" title="1.4.1 组合函数概念的理解"></a>1.4.1 组合函数概念的理解</h4><p>把依次调用的多个函数组合起来，让他们自动的依次调用，这个过程就是组合函数</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> num = <span class="number">100</span>;</span><br><span class="line"><span class="comment">//翻倍</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">double</span>(<span class="params">num</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> num * <span class="number">2</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//求平方</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">pow</span>(<span class="params">num</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> num ** <span class="number">2</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">pow</span>(<span class="title function_">double</span>(<span class="number">123</span>)));</span><br><span class="line"><span class="comment">//把上述两个函数结合起来</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">composeFn</span>(<span class="params">num</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="title function_">pow</span>(<span class="title function_">double</span>(num));</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">composeFn</span>(<span class="number">123</span>));</span><br></pre></td></tr></table></figure>

<h4 id="1-4-2-自动组合函数"><a href="#1-4-2-自动组合函数" class="headerlink" title="1.4.2 自动组合函数"></a>1.4.2 自动组合函数</h4><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">      考虑更加复杂的情况,比如传入了更多的函数，比如调用composeFn的时候传入了更多的参数</span></span><br><span class="line"><span class="comment">      */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//翻倍</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">double</span>(<span class="params">num</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> num * <span class="number">2</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//求平方</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">pow</span>(<span class="params">num</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> num ** <span class="number">3</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//封装:传入两个函数</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">composeFn</span>(<span class="params">...fns</span>) &#123;</span><br><span class="line">  <span class="comment">//用来做边界判断</span></span><br><span class="line">  <span class="keyword">let</span> length = fns.<span class="property">length</span>;</span><br><span class="line">  <span class="keyword">if</span> (length &lt;= <span class="number">0</span>) <span class="keyword">return</span>;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; length; i++) &#123;</span><br><span class="line">    <span class="comment">//此刻fn就是每一个函数</span></span><br><span class="line">    <span class="keyword">let</span> fn = fns[i];</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">typeof</span> fn !== <span class="string">&#x27;function&#x27;</span>) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">Error</span>(<span class="string">`第<span class="subst">$&#123;i&#125;</span>个参数必须是一个函数`</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//返回并调用新函数</span></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params">...args</span>) &#123;</span><br><span class="line">    <span class="comment">// let res = fns[0](...args)</span></span><br><span class="line">    <span class="keyword">let</span> res = fns[<span class="number">0</span>].<span class="title function_">apply</span>(<span class="variable language_">this</span>, args);</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">1</span>; i &lt; length; i++) &#123;</span><br><span class="line">      <span class="keyword">let</span> fn = fns[i];</span><br><span class="line">      <span class="comment">// res = fn.apply(this, [res]);</span></span><br><span class="line">      res = <span class="title function_">fn</span>(res);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="comment">// return pow(double(num));</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> newFn = <span class="title function_">composeFn</span>(double, pow, <span class="variable language_">console</span>.<span class="property">log</span>);</span><br><span class="line"><span class="title function_">newFn</span>(<span class="number">100</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> doubleRes = <span class="title function_">double</span>(<span class="number">100</span>);</span><br><span class="line"><span class="keyword">let</span> powRes = <span class="title function_">pow</span>(doubleRes);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(powRes);</span><br></pre></td></tr></table></figure>

<h3 id="1-5-with、eval"><a href="#1-5-with、eval" class="headerlink" title="1.5 with、eval"></a>1.5 with、eval</h3><p>with:扩展一个语句的作用域链<br>eval:执行字符串格式的 js 代码</p>
<h3 id="1-6-严格模式"><a href="#1-6-严格模式" class="headerlink" title="1.6 严格模式"></a>1.6 严格模式</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&#x27;use strict&#x27;</span>;</span><br><span class="line"><span class="comment">//1.不会意外的创建全局变量</span></span><br><span class="line"><span class="comment">// function foo() &#123;</span></span><br><span class="line"><span class="comment">//   abc = &#x27;123&#x27;;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// foo();</span></span><br><span class="line"><span class="comment">// console.log(abc);</span></span><br><span class="line"><span class="comment">//2. 发现静默的错误</span></span><br><span class="line"><span class="comment">// var obj = &#123;</span></span><br><span class="line"><span class="comment">//   name: &#x27;alex&#x27;,</span></span><br><span class="line"><span class="comment">// &#125;;</span></span><br><span class="line"><span class="comment">// Object.defineProperty(obj, &#x27;name&#x27;, &#123;</span></span><br><span class="line"><span class="comment">//   writable: false,</span></span><br><span class="line"><span class="comment">//   configurable: false,</span></span><br><span class="line"><span class="comment">// &#125;);</span></span><br><span class="line"><span class="comment">// obj.name = &#x27;dog&#x27;;</span></span><br><span class="line"><span class="comment">// console.log(obj.name);</span></span><br><span class="line"><span class="comment">//3. 参数名称不能相同</span></span><br><span class="line"><span class="comment">// function foo(num, num) &#123;&#125;</span></span><br><span class="line"><span class="comment">//4. 数字不能以0开头</span></span><br><span class="line"><span class="comment">// console.log(0123);</span></span><br><span class="line"><span class="comment">//5.eval</span></span><br><span class="line"><span class="comment">//6. this</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>(); <span class="comment">//undefined</span></span><br><span class="line">foo.<span class="title function_">apply</span>(<span class="string">&#x27;abc&#x27;</span>); <span class="comment">//String &#123;&#x27;abc&#x27;&#125;</span></span><br></pre></td></tr></table></figure>



<h2 id="2-对象"><a href="#2-对象" class="headerlink" title="2.对象"></a>2.对象</h2><h3 id="2-1-Object-defineProperty"><a href="#2-1-Object-defineProperty" class="headerlink" title="2.1 Object.defineProperty"></a>2.1 Object.defineProperty</h3><p>对对象的属性做精准的控制，属性描述符<br><code>Object.defineProperty(obj,prop,desciptor)</code><br>obj 要定义属性的对象<br>prop 属性名<br>desciptor 对该属性的描述</p>
<p>desciptor 有两种类型</p>
<ol>
<li>数据属性 Data</li>
<li>存取属性 Accessor</li>
</ol>
<p>详细的说明 :<a target="_blank" rel="noopener" href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty">https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty</a></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  <span class="attr">address</span>: <span class="string">&#x27;天河&#x27;</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">// Object.defineProperty(obj, &#x27;name&#x27;, &#123;</span></span><br><span class="line"><span class="comment">//   configurable: false, //该属性不可被删除</span></span><br><span class="line"><span class="comment">//   enumerable: false, //obj的name属性不可被枚举 for in Object.keys</span></span><br><span class="line"><span class="comment">//   writable: false, //该属性不能修改</span></span><br><span class="line"><span class="comment">//   value: &#x27;123&#x27;, //返回的值</span></span><br><span class="line"><span class="comment">// &#125;);</span></span><br><span class="line"><span class="comment">// delete obj.name;</span></span><br><span class="line"><span class="comment">// for (const key in obj) &#123;</span></span><br><span class="line"><span class="comment">//   console.log(key);</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// obj.name = &#x27;dog&#x27;;</span></span><br><span class="line"><span class="comment">// console.log(obj.name);</span></span><br><span class="line"><span class="comment">// //添加新的属性</span></span><br><span class="line"><span class="comment">// Object.defineProperty(obj, &#x27;height&#x27;, &#123;</span></span><br><span class="line"><span class="comment">//   value: 1.8,</span></span><br><span class="line"><span class="comment">// &#125;);</span></span><br><span class="line"><span class="keyword">let</span> _name;</span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">defineProperty</span>(obj, <span class="string">&#x27;name&#x27;</span>, &#123;</span><br><span class="line">  <span class="attr">configurable</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">enumerable</span>: <span class="literal">false</span>,</span><br><span class="line">  <span class="comment">//设置属性值时会自动调用</span></span><br><span class="line">  <span class="attr">set</span>: <span class="keyword">function</span> (<span class="params">value</span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;set被调用&#x27;</span>, value);</span><br><span class="line">    _name = value;</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="comment">//获取 时 自动调用</span></span><br><span class="line">  <span class="attr">get</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;get被调用了&#x27;</span>);</span><br><span class="line">    <span class="keyword">return</span> _name;</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">obj.<span class="property">name</span> = <span class="string">&#x27;123&#x27;</span>;</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//  让 a == 1 &amp;&amp; a == 2 &amp;&amp; a == 3; 为true</span></span><br><span class="line"><span class="keyword">let</span> i = <span class="number">1</span>;</span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">defineProperty</span>(<span class="variable language_">window</span>, <span class="string">&#x27;a&#x27;</span>, &#123;</span><br><span class="line">  <span class="attr">get</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> i++;</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a == <span class="number">1</span> &amp;&amp; a == <span class="number">2</span> &amp;&amp; a == <span class="number">3</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> obj = &#123;&#125;;</span><br><span class="line"><span class="comment">//定义多个新的属性</span></span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">defineProperties</span>(obj, &#123;</span><br><span class="line">  <span class="attr">name</span>: &#123;</span><br><span class="line">    <span class="attr">configurable</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">enumerable</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">writable</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">value</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">age</span>: &#123;&#125;,</span><br><span class="line">  <span class="attr">height</span>: &#123;&#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h3 id="2-2-一些新方法"><a href="#2-2-一些新方法" class="headerlink" title="2.2 一些新方法"></a>2.2 一些新方法</h3><ul>
<li>禁止对象扩展属性</li>
<li>密封对象 不允许你配置和删除属性</li>
<li>冻结对象 不允许修改现有属性</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// &#x27;use strict&#x27;;</span></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">18</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">//不允许扩展</span></span><br><span class="line"><span class="comment">// Object.preventExtensions(obj);</span></span><br><span class="line"><span class="comment">// obj.address = &#x27;123&#x27;;</span></span><br><span class="line"><span class="comment">// console.log(obj);</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//密封</span></span><br><span class="line"><span class="comment">// Object.seal(obj);</span></span><br><span class="line"><span class="comment">// delete obj.age;</span></span><br><span class="line"><span class="comment">// console.log(obj);</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//冻结对象</span></span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">freeze</span>(obj);</span><br><span class="line">obj.<span class="property">name</span> = <span class="string">&#x27;bbb&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj);</span><br></pre></td></tr></table></figure>

<h2 id="1-对象方法的补充"><a href="#1-对象方法的补充" class="headerlink" title="1. 对象方法的补充"></a>1. 对象方法的补充</h2><h3 id="1-1-hasOwnProperty"><a href="#1-1-hasOwnProperty" class="headerlink" title="1.1 hasOwnProperty"></a>1.1 hasOwnProperty</h3><p>对象是否有某个属于自己的属性(不是原型上的)</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">18</span>,</span><br><span class="line">&#125;;</span><br><span class="line">obj.<span class="property">__proto__</span>.<span class="property">address</span> = <span class="string">&#x27;天河&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="title function_">hasOwnProperty</span>(<span class="string">&#x27;name&#x27;</span>)); <span class="comment">//true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="title function_">hasOwnProperty</span>(<span class="string">&#x27;address&#x27;</span>)); <span class="comment">//false</span></span><br></pre></td></tr></table></figure>

<h3 id="1-2-in-操作符"><a href="#1-2-in-操作符" class="headerlink" title="1.2 in 操作符"></a>1.2 in 操作符</h3><p>判断某个属性是否在某个对象或者对象的原型上</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">18</span>,</span><br><span class="line">&#125;;</span><br><span class="line">obj.<span class="property">__proto__</span>.<span class="property">address</span> = <span class="string">&#x27;天河&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;name&#x27;</span> <span class="keyword">in</span> obj); <span class="comment">//true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;address&#x27;</span> <span class="keyword">in</span> obj); <span class="comment">//true</span></span><br><span class="line"><span class="comment">//for in 遍历的时候不仅仅是对象自身的也包括原型上的</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> key <span class="keyword">in</span> object) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(key);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="1-3-instanceof"><a href="#1-3-instanceof" class="headerlink" title="1.3 instanceof"></a>1.3 instanceof</h3><p>用于检测构造函数的 prototype 是否出现在某个实例对象的原型链上<br>就是用于判断对象和(类)构造函数之间的关系</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Student</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="comment">//为了把父构造函数体内的内容拿到</span></span><br><span class="line">  <span class="title class_">Person</span>.<span class="title function_">call</span>(<span class="variable language_">this</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//为了拿到原型上的内容</span></span><br><span class="line"><span class="title class_">Student</span>.<span class="property"><span class="keyword">prototype</span></span> = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line"><span class="keyword">var</span> stu = <span class="keyword">new</span> <span class="title class_">Student</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(stu <span class="keyword">instanceof</span> <span class="title class_">Student</span>); <span class="comment">//true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(stu <span class="keyword">instanceof</span> <span class="title class_">Person</span>); <span class="comment">//true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(stu <span class="keyword">instanceof</span> <span class="title class_">Function</span>); <span class="comment">//false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(stu <span class="keyword">instanceof</span> <span class="title class_">Object</span>); <span class="comment">//true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(stu <span class="keyword">instanceof</span> <span class="title class_">Array</span>); <span class="comment">//false</span></span><br></pre></td></tr></table></figure>

<h3 id="1-4-isPrototypeOf"><a href="#1-4-isPrototypeOf" class="headerlink" title="1.4 isPrototypeOf"></a>1.4 isPrototypeOf</h3><p>用于检测某个对象，是否出现在某个实例对象的原型链上<br>可以判断对象之间的继承关系</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Person</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">Student</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="comment">//为了把父构造函数体内的内容拿到</span></span><br><span class="line">  <span class="title class_">Person</span>.<span class="title function_">call</span>(<span class="variable language_">this</span>);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//为了拿到原型上的内容</span></span><br><span class="line"><span class="title class_">Student</span>.<span class="property"><span class="keyword">prototype</span></span> = <span class="title class_">Person</span>();</span><br><span class="line"><span class="keyword">var</span> stu = <span class="keyword">new</span> <span class="title class_">Student</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Student</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="title function_">isPrototypeOf</span>(stu)); <span class="comment">//true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="title function_">isPrototypeOf</span>(stu)); <span class="comment">//true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//判断对象之间的继承关系</span></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">28</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">createObject</span>(<span class="params">o</span>) &#123;</span><br><span class="line">  <span class="keyword">function</span> <span class="title function_">F</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line">  F.<span class="property"><span class="keyword">prototype</span></span> = o;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title function_">F</span>();</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//info是F的实例对象，obj赋值为F的原型</span></span><br><span class="line"><span class="comment">//info继承obj info子对象  obj父对象</span></span><br><span class="line"><span class="keyword">let</span> info = <span class="title function_">createObject</span>(obj);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="title function_">isPrototypeOf</span>(info)); <span class="comment">//true</span></span><br></pre></td></tr></table></figure>

<h2 id="2-class-方式定义类"><a href="#2-class-方式定义类" class="headerlink" title="2. class 方式定义类"></a>2. class 方式定义类</h2><h3 id="2-1-认识-class-定义类"><a href="#2-1-认识-class-定义类" class="headerlink" title="2.1 认识 class 定义类"></a>2.1 认识 class 定义类</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//es5定义类</span></span><br><span class="line"><span class="comment">// function Person()&#123;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//es6</span></span><br><span class="line"><span class="comment">// &#123;key:value&#125; 对象</span></span><br><span class="line"><span class="comment">// &#123;表达式&#125; 代码块</span></span><br><span class="line"><span class="comment">// &#123;&#125;-&gt;类的结构</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;&#125;</span><br><span class="line"><span class="keyword">let</span> alex = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line"><span class="keyword">let</span> jack = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(alex, jack);</span><br><span class="line"></span><br><span class="line"><span class="comment">//基本不用</span></span><br><span class="line"><span class="keyword">const</span> <span class="title class_">Student</span> = <span class="keyword">class</span> &#123;&#125;;</span><br><span class="line"><span class="keyword">const</span> foo = <span class="keyword">function</span> (<span class="params"></span>) &#123;&#125;;</span><br><span class="line"><span class="keyword">let</span> aa = <span class="keyword">new</span> <span class="title class_">Student</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(aa);</span><br></pre></td></tr></table></figure>

<h3 id="2-2-class-类中的内容"><a href="#2-2-class-类中的内容" class="headerlink" title="2.2 class 类中的内容"></a>2.2 class 类中的内容</h3><p>new 的时候发生了什么事:会调用构造函数的 constructor，并执行如下操作，在内存中创建一个新的空对象；这个对象内部的<code>__proto__</code>属性会被赋值该构造函数的 prototype 属性；构造函数内的 this 会指向创建出来的新对象；执行构造函数体内的代码；如果构造函数没有返回非空对象，则返回创建出来的对象。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">  <span class="comment">//当我们通过new操作符，默认调用class中的constructor</span></span><br><span class="line">  <span class="comment">//名称固定的，而且每个class只能有一个constructor</span></span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//实例方法</span></span><br><span class="line">  <span class="comment">//本质上 放在Person.prototype上</span></span><br><span class="line">  <span class="title function_">running</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span> + <span class="string">&#x27;疯狂的跑&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">eating</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span> + <span class="string">&#x27;嘎嘎炫&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> obj = <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span> === obj.<span class="property">__proto__</span>); <span class="comment">//true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Person</span>.<span class="property">running</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Person</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">running</span>);</span><br></pre></td></tr></table></figure>

<h3 id="2-3-类和构造函数的区别"><a href="#2-3-类和构造函数的区别" class="headerlink" title="2.3 类和构造函数的区别"></a>2.3 类和构造函数的区别</h3><p>class 定义的类不能作为普通函数去调用,必须和 new 连用</p>
<h3 id="2-4-类的访问器方法"><a href="#2-4-类的访问器方法" class="headerlink" title="2.4 类的访问器方法"></a>2.4 类的访问器方法</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//对象的访问器</span></span><br><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  <span class="attr">_name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">defineProperty</span>(obj, <span class="string">&#x27;name&#x27;</span>, &#123;</span><br><span class="line">  <span class="attr">configurable</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">enumerable</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="title function_">set</span>(<span class="params"></span>) &#123;&#125;,</span><br><span class="line">  <span class="title function_">get</span>(<span class="params"></span>) &#123;&#125;,</span><br><span class="line">&#125;);</span><br><span class="line"><span class="keyword">let</span> obj2 = &#123;</span><br><span class="line">  <span class="attr">_name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  <span class="keyword">set</span> <span class="title function_">name</span>(<span class="params">value</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">_name</span> = value;</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="keyword">get</span> <span class="title function_">name</span>() &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_name</span>;</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">//类的访问器</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">  <span class="comment">//coder之间的约定 _开头的属性方法，不在外界访问</span></span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">_name</span> = name;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">set</span> <span class="title function_">name</span>(<span class="params">value</span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;设置name&#x27;</span>);</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">_name</span> = value;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">get</span> <span class="title function_">name</span>() &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;获取name&#x27;</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="variable language_">this</span>.<span class="property">_name</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> p1 = <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>);</span><br><span class="line"><span class="comment">//访问器的应用场景</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Rectangle</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">x, y, width, height</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">x</span> = x;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">y</span> = y;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">width</span> = width;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">height</span> = height;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">get</span> <span class="title function_">position</span>() &#123;</span><br><span class="line">    <span class="keyword">return</span> &#123; <span class="attr">x</span>: <span class="variable language_">this</span>.<span class="property">x</span>, <span class="attr">y</span>: <span class="variable language_">this</span>.<span class="property">y</span> &#125;;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">get</span> <span class="title function_">size</span>() &#123;</span><br><span class="line">    <span class="keyword">return</span> &#123; <span class="attr">width</span>: <span class="variable language_">this</span>.<span class="property">width</span>, <span class="attr">height</span>: <span class="variable language_">this</span>.<span class="property">height</span> &#125;;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> rect1 = <span class="keyword">new</span> <span class="title class_">Rectangle</span>(<span class="number">10</span>, <span class="number">20</span>, <span class="number">100</span>, <span class="number">200</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(rect1.<span class="property">position</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(rect1.<span class="property">size</span>);</span><br></pre></td></tr></table></figure>

<h2 id="3-extends-实现继承"><a href="#3-extends-实现继承" class="headerlink" title="3. extends 实现继承"></a>3. extends 实现继承</h2><h3 id="3-1-继承"><a href="#3-1-继承" class="headerlink" title="3.1 继承"></a>3.1 继承</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//定义父类</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">name</span> = name;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">age</span> = age;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">running</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;明天🏃&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">eating</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;明天吃KFC&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Person</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name, age, sno, score</span>) &#123;</span><br><span class="line">    <span class="comment">//子类的构造函数</span></span><br><span class="line">    <span class="comment">//super必须写在所有的this之前</span></span><br><span class="line">    <span class="variable language_">super</span>(name, age);</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">sno</span> = sno;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">score</span> = score;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">studying</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;不开灯的卷&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> stu = <span class="keyword">new</span> <span class="title class_">Student</span>(<span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>, <span class="number">111</span>, <span class="number">59</span>);</span><br><span class="line">stu.<span class="title function_">eating</span>();</span><br><span class="line">stu.<span class="title function_">running</span>();</span><br><span class="line">stu.<span class="title function_">studying</span>();</span><br></pre></td></tr></table></figure>

<h3 id="3-2-super-关键字"><a href="#3-2-super-关键字" class="headerlink" title="3.2 super 关键字"></a>3.2 super 关键字</h3><p>super 使用的位置有三个，子类的构造函数，实例方法，静态方法</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Animal</span> &#123;</span><br><span class="line">  <span class="title function_">running</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🏃&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="title function_">eating</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🍽️&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//静态方法,给类用的</span></span><br><span class="line">  <span class="keyword">static</span> <span class="title function_">sleep</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;没日没夜的睡&#x27;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Dog</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Animal</span> &#123;</span><br><span class="line">  <span class="comment">//子类如果对父类的方法不满意(继承过来的方法)</span></span><br><span class="line">  <span class="comment">//重新实现--重写</span></span><br><span class="line">  <span class="title function_">running</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;四条腿跑&#x27;</span>);</span><br><span class="line">    <span class="comment">//调用父类方法</span></span><br><span class="line">    <span class="variable language_">super</span>.<span class="title function_">running</span>();</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">static</span> <span class="title function_">sleep</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;趴着&#x27;</span>);</span><br><span class="line">    <span class="variable language_">super</span>.<span class="title function_">sleep</span>();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> dog = <span class="keyword">new</span> <span class="title class_">Dog</span>();</span><br><span class="line">dog.<span class="title function_">running</span>();</span><br><span class="line">dog.<span class="title function_">eating</span>();</span><br><span class="line"><span class="title class_">Dog</span>.<span class="title function_">sleep</span>();</span><br></pre></td></tr></table></figure>

<h3 id="3-3-继承内置类"><a href="#3-3-继承内置类" class="headerlink" title="3.3 继承内置类"></a>3.3 继承内置类</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//队列 第一个元素  最后一个元素</span></span><br><span class="line"><span class="comment">// class myArray extends Array &#123;</span></span><br><span class="line"><span class="comment">//   get lastItem() &#123;</span></span><br><span class="line"><span class="comment">//     return this[this.length - 1];</span></span><br><span class="line"><span class="comment">//   &#125;</span></span><br><span class="line"><span class="comment">//   get firstItem() &#123;</span></span><br><span class="line"><span class="comment">//     return this[0];</span></span><br><span class="line"><span class="comment">//   &#125;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// let arr = new myArray(10, 20, 30);</span></span><br><span class="line"><span class="comment">// // console.log(arr.firstItem, arr.lastItem);</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//另一种方式</span></span><br><span class="line"><span class="title class_">Array</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">lastItem</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="variable language_">this</span>[<span class="variable language_">this</span>.<span class="property">length</span> - <span class="number">1</span>];</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">let</span> arr = <span class="keyword">new</span> <span class="title class_">Array</span>(<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr.<span class="property">__proto__</span> === <span class="title class_">Array</span>.<span class="property"><span class="keyword">prototype</span></span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr.<span class="title function_">lastItem</span>());</span><br></pre></td></tr></table></figure>

<h2 id="4-多态概念的理解"><a href="#4-多态概念的理解" class="headerlink" title="4. 多态概念的理解"></a>4. 多态概念的理解</h2><p>面向对象的三大特性:封装、继承、多态<br>私人:不同数据类型，同一个操作，表现出不同的行为，就是多态的体现</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">sum</span>(<span class="params">a, b</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(a + b);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">sum</span>(<span class="number">1</span>, <span class="number">2</span>); <span class="comment">//3</span></span><br><span class="line"><span class="title function_">sum</span>(<span class="string">&#x27;1&#x27;</span>, <span class="number">2</span>); <span class="comment">//12</span></span><br></pre></td></tr></table></figure>

<h2 id="5-补充"><a href="#5-补充" class="headerlink" title="5. 补充"></a>5. 补充</h2><h3 id="5-1-对象字面量的增强写法"><a href="#5-1-对象字面量的增强写法" class="headerlink" title="5.1 对象字面量的增强写法"></a>5.1 对象字面量的增强写法</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">     1. 属性</span></span><br><span class="line"><span class="comment">     2. 方法</span></span><br><span class="line"><span class="comment">     3. 计算属性名</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line"><span class="keyword">let</span> name = <span class="string">&#x27;alex&#x27;</span>;</span><br><span class="line"><span class="keyword">let</span> age = <span class="number">18</span>;</span><br><span class="line"><span class="keyword">let</span> key = <span class="string">&#x27;address&#x27;</span> + <span class="string">&#x27;city&#x27;</span>;</span><br><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  name,</span><br><span class="line">  age,</span><br><span class="line">  <span class="title function_">eating</span>(<span class="params"></span>) &#123;&#125;,</span><br><span class="line">  [key]: <span class="string">&#x27;广州&#x27;</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj);</span><br></pre></td></tr></table></figure>

<h3 id="5-2-回顾函数的原型"><a href="#5-2-回顾函数的原型" class="headerlink" title="5.2 回顾函数的原型"></a>5.2 回顾函数的原型</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//foo.__proto__ === Function.prototype</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>, name, age);</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">test</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"><span class="comment">//函数对象中的某些方法来自于Function.prototype</span></span><br><span class="line">foo.<span class="title function_">apply</span>(<span class="string">&#x27;abc&#x27;</span>, [<span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>]);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(foo.<span class="property">apply</span> === <span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">apply</span>);</span><br><span class="line"><span class="comment">//我在 Function.prototype添加的属性和方法 所有函数都能用</span></span><br><span class="line"><span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">info</span> = <span class="string">&#x27;hello alex&#x27;</span>;</span><br><span class="line">foo.<span class="property">info</span>;</span><br><span class="line">test.<span class="property">info</span>;</span><br><span class="line"><span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">bar</span> = <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;bar~~~~~~&#x27;</span>);</span><br><span class="line">&#125;;</span><br><span class="line">foo.<span class="title function_">bar</span>();</span><br><span class="line">test.<span class="title function_">bar</span>();</span><br><span class="line"><span class="comment">//Array.prototype.slice.apply(arguments)</span></span><br><span class="line"><span class="comment">// [].slice.apply(arguments)</span></span><br></pre></td></tr></table></figure>

<h3 id="5-3-手写-apply"><a href="#5-3-手写-apply" class="headerlink" title="5.3 手写 apply"></a>5.3 手写 apply</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//apply的实现</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>, name, age);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// foo.apply(&#x27;aaa&#x27;, [&#x27;alex&#x27;, 18]);</span></span><br><span class="line"><span class="comment">//1.给所有函数添加myapply</span></span><br><span class="line"><span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">myapply</span> = <span class="keyword">function</span> (<span class="params">thisArg, otherArgs</span>) &#123;</span><br><span class="line">  <span class="comment">//thisArg-&gt;this</span></span><br><span class="line">  <span class="comment">//otherArgs剩下的参数 -&gt; 那个数组</span></span><br><span class="line">  <span class="comment">//获取thisArg,确保他是一个对象类型</span></span><br><span class="line">  thisArg =</span><br><span class="line">    thisArg === <span class="literal">null</span> || thisArg === <span class="literal">undefined</span> ? <span class="variable language_">window</span> : <span class="title class_">Object</span>(thisArg);</span><br><span class="line">  <span class="comment">//调用前面的函数</span></span><br><span class="line">  <span class="comment">//定义对象上的方法，我之后调用</span></span><br><span class="line">  <span class="title class_">Object</span>.<span class="title function_">defineProperty</span>(thisArg, <span class="string">&#x27;fn&#x27;</span>, &#123;</span><br><span class="line">    <span class="attr">enumerable</span>: <span class="literal">false</span>,</span><br><span class="line">    <span class="attr">configurable</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="comment">//具体fn里面放的是什么</span></span><br><span class="line">    <span class="attr">value</span>: <span class="variable language_">this</span>,</span><br><span class="line">  &#125;);</span><br><span class="line">  thisArg.<span class="title function_">fn</span>(...otherArgs);</span><br><span class="line">  <span class="comment">//调用完以后删除fn 避免副作用</span></span><br><span class="line">  <span class="keyword">delete</span> thisArg.<span class="property">fn</span>;</span><br><span class="line">&#125;;</span><br><span class="line">foo.<span class="title function_">myapply</span>(<span class="string">&#x27;aaa&#x27;</span>, [<span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>]);</span><br><span class="line">foo.<span class="title function_">myapply</span>(<span class="string">&#x27;aaa&#x27;</span>, [<span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>]);</span><br><span class="line">foo.<span class="title function_">myapply</span>(<span class="literal">null</span>, [<span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>]);</span><br></pre></td></tr></table></figure>

<h3 id="5-4-手写-call"><a href="#5-4-手写-call" class="headerlink" title="5.4 手写 call"></a>5.4 手写 call</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//call的实现</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>, name, age);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// foo.apply(&#x27;aaa&#x27;, [&#x27;alex&#x27;, 18]);</span></span><br><span class="line"><span class="comment">//1.给所有函数添加mycall</span></span><br><span class="line"><span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">mycall</span> = <span class="keyword">function</span> (<span class="params">thisArg, ...otherArgs</span>) &#123;</span><br><span class="line">  <span class="comment">//thisArg-&gt;this</span></span><br><span class="line">  <span class="comment">//otherArgs剩下的参数 -&gt; 那个数组</span></span><br><span class="line">  <span class="comment">//获取thisArg,确保他是一个对象类型</span></span><br><span class="line">  thisArg =</span><br><span class="line">    thisArg === <span class="literal">null</span> || thisArg === <span class="literal">undefined</span> ? <span class="variable language_">window</span> : <span class="title class_">Object</span>(thisArg);</span><br><span class="line">  <span class="comment">//调用前面的函数</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">//定义对象上的方法，我之后调用</span></span><br><span class="line">  <span class="title class_">Object</span>.<span class="title function_">defineProperty</span>(thisArg, <span class="string">&#x27;fn&#x27;</span>, &#123;</span><br><span class="line">    <span class="attr">enumerable</span>: <span class="literal">false</span>,</span><br><span class="line">    <span class="attr">configurable</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="comment">//具体fn里面放的是什么</span></span><br><span class="line">    <span class="attr">value</span>: <span class="variable language_">this</span>,</span><br><span class="line">  &#125;);</span><br><span class="line">  thisArg.<span class="title function_">fn</span>(...otherArgs);</span><br><span class="line">  <span class="comment">//调用完以后删除fn 避免副作用</span></span><br><span class="line">  <span class="keyword">delete</span> thisArg.<span class="property">fn</span>;</span><br><span class="line">&#125;;</span><br><span class="line">foo.<span class="title function_">mycall</span>(<span class="string">&#x27;aaa&#x27;</span>, <span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>);</span><br><span class="line">foo.<span class="title function_">mycall</span>(<span class="string">&#x27;aaa&#x27;</span>, <span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>);</span><br><span class="line">foo.<span class="title function_">mycall</span>(<span class="literal">null</span>, <span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>);</span><br></pre></td></tr></table></figure>

<h3 id="5-5-call-apply-抽取封装"><a href="#5-5-call-apply-抽取封装" class="headerlink" title="5.5 call-apply 抽取封装"></a>5.5 call-apply 抽取封装</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//call的实现</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>, name, age);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 封装到独立的函数中</span></span><br><span class="line"><span class="comment">// function execFn(thisArg, otherArgs, fn) &#123;</span></span><br><span class="line"><span class="comment">//   //保证thisArg是一个对象</span></span><br><span class="line"><span class="comment">//   thisArg =</span></span><br><span class="line"><span class="comment">//     thisArg === null || thisArg === undefined ? window : Object(thisArg);</span></span><br><span class="line"><span class="comment">//   // thisArg.fn = this;</span></span><br><span class="line"><span class="comment">//   Object.defineProperty(thisArg, &#x27;fn&#x27;, &#123;</span></span><br><span class="line"><span class="comment">//     enumerable: false,</span></span><br><span class="line"><span class="comment">//     configurable: true,</span></span><br><span class="line"><span class="comment">//     value: fn,</span></span><br><span class="line"><span class="comment">//   &#125;);</span></span><br><span class="line"><span class="comment">//   thisArg.fn(...otherArgs);</span></span><br><span class="line"><span class="comment">//   delete fn;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">//封装到原型上 我的exec里面已经能call 也能apply了</span></span><br><span class="line"><span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">myexec</span> = <span class="keyword">function</span> (<span class="params">thisArg, otherArgs</span>) &#123;</span><br><span class="line">  thisArg =</span><br><span class="line">    thisArg === <span class="literal">null</span> || thisArg === <span class="literal">undefined</span> ? <span class="variable language_">window</span> : <span class="title class_">Object</span>(thisArg);</span><br><span class="line">  <span class="title class_">Object</span>.<span class="title function_">defineProperty</span>(thisArg, <span class="string">&#x27;fn&#x27;</span>, &#123;</span><br><span class="line">    <span class="attr">enumerable</span>: <span class="literal">false</span>,</span><br><span class="line">    <span class="attr">configurable</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">value</span>: <span class="variable language_">this</span>,</span><br><span class="line">  &#125;);</span><br><span class="line">  thisArg.<span class="title function_">fn</span>(...otherArgs);</span><br><span class="line">  <span class="keyword">delete</span> thisArg.<span class="property">fn</span>;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">//1. 给每个函数添加 myapply</span></span><br><span class="line"><span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">myapply</span> = <span class="keyword">function</span> (<span class="params">thisArg, otherArgs</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="title function_">myexec</span>(thisArg, otherArgs);</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">//2. 给每个函数添加 mycall</span></span><br><span class="line"><span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">mycall</span> = <span class="keyword">function</span> (<span class="params">thisArg, ...otherArgs</span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="title function_">myexec</span>(thisArg, otherArgs);</span><br><span class="line">&#125;;</span><br><span class="line">foo.<span class="title function_">mycall</span>(<span class="string">&#x27;aaa&#x27;</span>, <span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>);</span><br><span class="line">foo.<span class="title function_">myapply</span>(<span class="string">&#x27;aaa&#x27;</span>, [<span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>]);</span><br><span class="line"><span class="comment">// foo.mycall(null, &#x27;alex&#x27;, 18);</span></span><br></pre></td></tr></table></figure>

<h3 id="手写-bind"><a href="#手写-bind" class="headerlink" title="手写 bind"></a>手写 bind</h3><p>相比上面，不用调用而是返回这个 fn</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">name, age, height, address</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>, name, age, height, address);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">mybind</span> = <span class="keyword">function</span> (<span class="params">thisArg, ...otherArgs</span>) &#123;</span><br><span class="line">  thisArg =</span><br><span class="line">    thisArg === <span class="literal">null</span> || thisArg === <span class="literal">undefined</span> ? <span class="variable language_">window</span> : <span class="title class_">Object</span>(thisArg);</span><br><span class="line">  <span class="title class_">Object</span>.<span class="title function_">defineProperty</span>(thisArg, <span class="string">&#x27;fn&#x27;</span>, &#123;</span><br><span class="line">    <span class="attr">enumerable</span>: <span class="literal">false</span>,</span><br><span class="line">    <span class="attr">configurable</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">value</span>: <span class="variable language_">this</span>,</span><br><span class="line">  &#125;);</span><br><span class="line">  <span class="comment">// thisArg.fn(...otherArgs);</span></span><br><span class="line">  <span class="comment">// delete thisArg.fn;</span></span><br><span class="line">  <span class="comment">//我要返回一个fn，而不是调用他</span></span><br><span class="line">  <span class="comment">//他的实参个数确定吗？不确定 rest</span></span><br><span class="line">  <span class="keyword">return</span> <span class="function">(<span class="params">...newArgs</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="comment">//原来的参数 我也不能丢</span></span><br><span class="line">    <span class="keyword">let</span> allArgs = [...otherArgs, ...newArgs];</span><br><span class="line">    thisArg.<span class="title function_">fn</span>(...allArgs);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">let</span> newFoo = foo.<span class="title function_">bind</span>(<span class="string">&#x27;abc&#x27;</span>, <span class="string">&#x27;alex&#x27;</span>, <span class="number">18</span>);</span><br><span class="line"><span class="title function_">newFoo</span>(<span class="number">1.88</span>, <span class="number">18888</span>);</span><br></pre></td></tr></table></figure>

<h2 id="ES6"><a href="#ES6" class="headerlink" title="ES6"></a>ES6</h2><h2 id="1-函数"><a href="#1-函数" class="headerlink" title="1. 函数"></a>1. 函数</h2><h3 id="1-1-默认参数"><a href="#1-1-默认参数" class="headerlink" title="1.1 默认参数"></a>1.1 默认参数</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//es6开始有默认值了 默认参数不会对null做处理</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">arg1, arg2</span>) &#123;</span><br><span class="line">  <span class="comment">// //第一种写法</span></span><br><span class="line">  <span class="comment">// arg1 = arg1 ? arg1 : &#x27;我是默认值&#x27;;</span></span><br><span class="line">  <span class="comment">// //第二种写法</span></span><br><span class="line">  <span class="comment">// arg1 = arg1 || &#x27;我是默认值&#x27;;</span></span><br><span class="line">  <span class="comment">// //上述两种写法都不够严谨</span></span><br><span class="line">  <span class="comment">// arg1 = arg1 === undefined || arg1 === null ? &#x27;我是默认值&#x27; : arg1;</span></span><br><span class="line">  <span class="comment">// console.log(arg1);</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">//es6+的语法 ??能够处理null</span></span><br><span class="line">  arg1 = arg1 ?? <span class="string">&#x27;我是默认值&#x27;</span>;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(arg1);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>(<span class="number">123</span>);</span><br><span class="line"><span class="title function_">foo</span>(<span class="string">&#x27;123&#x27;</span>);</span><br><span class="line"><span class="title function_">foo</span>(<span class="string">&#x27;&#x27;</span>);</span><br><span class="line"><span class="title function_">foo</span>(<span class="literal">false</span>);</span><br><span class="line"><span class="title function_">foo</span>(<span class="literal">null</span>);</span><br><span class="line"><span class="title function_">foo</span>(<span class="number">0</span>);</span><br><span class="line"><span class="title function_">foo</span>(<span class="literal">undefined</span>);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//最好把有默认参数的形参放到最后面，但还是会按照顺序来匹配</span></span><br><span class="line"><span class="comment">//默认值会改变函数的length，默认值以及后面的参数都不算在length中</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">age, name, height = <span class="number">1.88</span>, ...args</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(name, age, height);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">foo</span>(<span class="number">18</span>, <span class="string">&#x27;alex&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//默认值可以和解构一起使用</span></span><br><span class="line"><span class="comment">// const obj = &#123; name: &#x27;alex&#x27; &#125;;</span></span><br><span class="line"><span class="comment">// const &#123; name = &#x27;jack&#x27; &#125; = obj;</span></span><br><span class="line"><span class="comment">// function bar(obj = &#123; name: &#x27;alex&#x27;, age: 18 &#125;) &#123;</span></span><br><span class="line"><span class="comment">//   console.log(obj.name, obj.age);</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="comment">// bar();</span></span><br><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">18</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">function</span> <span class="title function_">bar</span>(<span class="params">&#123; name, age &#125; = obj</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(name, age);</span><br><span class="line">&#125;</span><br><span class="line"><span class="title function_">bar</span>();</span><br></pre></td></tr></table></figure>

<h3 id="1-2-箭头函数补充"><a href="#1-2-箭头函数补充" class="headerlink" title="1.2 箭头函数补充"></a>1.2 箭头函数补充</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;&#125;</span><br><span class="line"><span class="keyword">let</span> f = <span class="keyword">new</span> <span class="title function_">foo</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(foo.<span class="property">__proto__</span>); <span class="comment">//Function.prototype</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(foo.<span class="property"><span class="keyword">prototype</span></span> === f.<span class="property">__proto__</span>); <span class="comment">// new Foo()-&gt; f.__proto__ === Foo.prototype</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> <span class="title function_">bar</span> = (<span class="params"></span>) =&gt; &#123;&#125;;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(bar.<span class="property">__proto__</span> === <span class="title class_">Function</span>.<span class="property"><span class="keyword">prototype</span></span>); <span class="comment">//true</span></span><br><span class="line"><span class="comment">//箭头函数没有显示原型</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(bar.<span class="property"><span class="keyword">prototype</span></span>); <span class="comment">//undefined</span></span><br><span class="line"><span class="keyword">let</span> b = <span class="keyword">new</span> <span class="title function_">bar</span>(); <span class="comment">//报错</span></span><br></pre></td></tr></table></figure>

<h2 id="2-展开运算符"><a href="#2-展开运算符" class="headerlink" title="2. 展开运算符"></a>2. 展开运算符</h2><h3 id="2-1-展开的基本使用"><a href="#2-1-展开的基本使用" class="headerlink" title="2.1 展开的基本使用"></a>2.1 展开的基本使用</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> str = <span class="string">&#x27;helloworld&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(...str);</span><br><span class="line"><span class="comment">//1.数组构造时使用</span></span><br><span class="line"><span class="keyword">const</span> names = [<span class="string">&#x27;abc&#x27;</span>, <span class="string">&#x27;cba&#x27;</span>, <span class="string">&#x27;nba&#x27;</span>, <span class="string">&#x27;mba&#x27;</span>];</span><br><span class="line"><span class="keyword">const</span> newNames = [...names, <span class="string">&#x27;aa&#x27;</span>, <span class="string">&#x27;bb&#x27;</span>];</span><br><span class="line"><span class="comment">//2. 函数的剩余参数</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">name1, name2, ...args</span>) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(name1, name2, args);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//3. 函数调用时使用</span></span><br><span class="line"><span class="title function_">foo</span>(...names);</span><br><span class="line"><span class="title function_">foo</span>(...str);</span><br><span class="line"><span class="comment">//4. 对象</span></span><br><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">18</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">const</span> info = &#123;</span><br><span class="line">  ...obj,</span><br><span class="line">  <span class="attr">height</span>: <span class="number">1.88</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">//不能这样做， 因为obj无法迭代</span></span><br><span class="line"><span class="title function_">foo</span>(...obj);</span><br><span class="line"><span class="comment">//可迭代对象：数组/string/arguments</span></span><br></pre></td></tr></table></figure>

<h3 id="2-2-引用赋值和深浅拷贝"><a href="#2-2-引用赋值和深浅拷贝" class="headerlink" title="2.2 引用赋值和深浅拷贝"></a>2.2 引用赋值和深浅拷贝</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  <span class="attr">friend</span>: &#123;</span><br><span class="line">    <span class="attr">name</span>: <span class="string">&#x27;autoCurry&#x27;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">// //引用赋值</span></span><br><span class="line"><span class="comment">// const info = obj;</span></span><br><span class="line"><span class="comment">// // info.name = 123;</span></span><br><span class="line"><span class="comment">// //浅拷贝:只拷贝第一层</span></span><br><span class="line"><span class="comment">// const info1 = &#123;</span></span><br><span class="line"><span class="comment">//   ...obj,</span></span><br><span class="line"><span class="comment">// &#125;;</span></span><br><span class="line"><span class="comment">// info1.name = &#x27;哈哈哈&#x27;;</span></span><br><span class="line"><span class="comment">// console.log(obj.name); //alex</span></span><br><span class="line"><span class="comment">// console.log(info1.name);</span></span><br><span class="line"><span class="comment">// info1.friend.name = &#x27;mybind&#x27;;</span></span><br><span class="line"><span class="comment">// console.log(obj.friend.name); //mybind</span></span><br><span class="line"><span class="comment">// console.log(info1.friend.name); //mybind</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//深拷贝</span></span><br><span class="line"><span class="comment">//1.库</span></span><br><span class="line"><span class="comment">//2.自己实现</span></span><br><span class="line"><span class="comment">//3.利用现有机制</span></span><br><span class="line"><span class="comment">//把对象序列化</span></span><br><span class="line"><span class="comment">// let a = JSON.stringify(obj);</span></span><br><span class="line"><span class="comment">// console.log(a);</span></span><br><span class="line"><span class="comment">// //反序列化</span></span><br><span class="line"><span class="comment">// let b = JSON.parse(a);</span></span><br><span class="line"><span class="comment">// console.log(b);</span></span><br><span class="line"><span class="keyword">let</span> info2 = <span class="title class_">JSON</span>.<span class="title function_">parse</span>(<span class="title class_">JSON</span>.<span class="title function_">stringify</span>(obj));</span><br><span class="line"><span class="comment">// console.log(info2);</span></span><br><span class="line">info2.<span class="property">friend</span>.<span class="property">name</span> = <span class="string">&#x27;我是info2哈哈哈&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj, info2);</span><br></pre></td></tr></table></figure>

<h2 id="3-Symbol"><a href="#3-Symbol" class="headerlink" title="3. Symbol"></a>3. Symbol</h2><p>生成独一无二的值</p>
<h3 id="3-1-初识-symbol"><a href="#3-1-初识-symbol" class="headerlink" title="3.1 初识 symbol"></a>3.1 初识 symbol</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> s1 = <span class="title class_">Symbol</span>();</span><br><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;aaaaaaalex&#x27;</span>,</span><br><span class="line">  [s1]: <span class="string">&#x27;aaa&#x27;</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">const</span> s2 = <span class="title class_">Symbol</span>();</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(s1 == s2); <span class="comment">//false</span></span><br><span class="line">obj[s2] = <span class="string">&#x27;bbb&#x27;</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj);</span><br></pre></td></tr></table></figure>

<h3 id="3-2-symbol-注意和-api"><a href="#3-2-symbol-注意和-api" class="headerlink" title="3.2 symbol 注意和 api"></a>3.2 symbol 注意和 api</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> s1 = <span class="title class_">Symbol</span>();</span><br><span class="line"><span class="keyword">const</span> s2 = <span class="title class_">Symbol</span>();</span><br><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span>,</span><br><span class="line">  [s1]: <span class="string">&#x27;aa&#x27;</span>,</span><br><span class="line">  [s2]: <span class="string">&#x27;bb&#x27;</span>,</span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">const</span> obj1 = &#123;&#125;;</span><br><span class="line">obj1[s1] = <span class="string">&#x27;aa&#x27;</span>;</span><br><span class="line">obj1[s2] = <span class="string">&#x27;bb&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> obj2 = &#123;&#125;;</span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">defineProperty</span>(obj2, s1, &#123;</span><br><span class="line">  <span class="attr">value</span>: <span class="string">&#x27;aaa&#x27;</span>,</span><br><span class="line">&#125;);</span><br><span class="line"><span class="comment">//有方法获取symbol的key</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">keys</span>(obj)); <span class="comment">//拿不到symbol的key</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">getOwnPropertySymbols</span>(obj)); <span class="comment">//只能拿symbol的key</span></span><br><span class="line"><span class="keyword">const</span> symbolKeys = <span class="title class_">Object</span>.<span class="title function_">getOwnPropertySymbols</span>(obj);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> key <span class="keyword">of</span> symbolKeys) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(obj[key]);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> s3 = <span class="title class_">Symbol</span>(<span class="string">&#x27;ccc&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(s3);</span><br><span class="line"><span class="comment">//相当于是Symbol的key</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(s3.<span class="property">description</span>);</span><br><span class="line"><span class="keyword">const</span> s4 = <span class="title class_">Symbol</span>(s3.<span class="property">description</span>);</span><br><span class="line"><span class="comment">//哪怕是同一个key 还是false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(s3 === s4); <span class="comment">//false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//我非要相同的Symbol</span></span><br><span class="line"><span class="comment">//如果你有相同的key，可以通过Symbol.for生成相同的Symbol值</span></span><br><span class="line"><span class="keyword">const</span> s5 = <span class="title class_">Symbol</span>.<span class="title function_">for</span>(<span class="string">&#x27;ddd&#x27;</span>);</span><br><span class="line"><span class="keyword">const</span> s6 = <span class="title class_">Symbol</span>.<span class="title function_">for</span>(<span class="string">&#x27;ddd&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(s5 === s6); <span class="comment">//true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//获取传入的key，后面可能用key生成相同的symbol</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Symbol</span>.<span class="title function_">keyFor</span>(s5));</span><br></pre></td></tr></table></figure>

<h2 id="4-Set-集合"><a href="#4-Set-集合" class="headerlink" title="4. Set 集合"></a>4. Set 集合</h2><p>类似数组，但是最大区别是天生不允许重复。只能通过构造函数来创建</p>
<h3 id="4-1-set"><a href="#4-1-set" class="headerlink" title="4.1 set"></a>4.1 set</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> set = <span class="keyword">new</span> <span class="title class_">Set</span>();</span><br><span class="line"><span class="comment">// console.log(set);</span></span><br><span class="line"><span class="comment">//添加元素</span></span><br><span class="line">set.<span class="title function_">add</span>(<span class="number">10</span>);</span><br><span class="line">set.<span class="title function_">add</span>(<span class="number">20</span>);</span><br><span class="line">set.<span class="title function_">add</span>(<span class="number">22</span>);</span><br><span class="line"><span class="comment">//做了添加重复的元素，但是没用</span></span><br><span class="line">set.<span class="title function_">add</span>(<span class="number">22</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(set);</span><br><span class="line"><span class="comment">// const info = &#123;&#125;;</span></span><br><span class="line"><span class="keyword">const</span> obj = &#123;&#125;;</span><br><span class="line"><span class="comment">// set.add(info);</span></span><br><span class="line"><span class="comment">// set.add(obj);</span></span><br><span class="line"><span class="comment">//可以添加，obj和info是两个不同的对象</span></span><br><span class="line"><span class="comment">// console.log(set);</span></span><br><span class="line"><span class="comment">// set.add(obj); //没用，因为重复</span></span><br><span class="line"><span class="comment">// console.log(set);</span></span><br><span class="line"><span class="comment">//set的应用场景 去重</span></span><br><span class="line"><span class="keyword">const</span> names = [<span class="string">&#x27;abc&#x27;</span>, <span class="string">&#x27;abc&#x27;</span>, <span class="string">&#x27;cba&#x27;</span>, <span class="string">&#x27;cba&#x27;</span>, <span class="string">&#x27;nba&#x27;</span>, <span class="string">&#x27;mba&#x27;</span>];</span><br><span class="line"><span class="comment">// const newNames = [];</span></span><br><span class="line"><span class="comment">// for (const item of names) &#123;</span></span><br><span class="line"><span class="comment">//   if (!newNames.includes(item)) &#123;</span></span><br><span class="line"><span class="comment">//     newNames.push(item);</span></span><br><span class="line"><span class="comment">//   &#125;</span></span><br><span class="line"><span class="comment">// &#125;</span></span><br><span class="line"><span class="keyword">const</span> newNamesSet = <span class="keyword">new</span> <span class="title class_">Set</span>(names);</span><br><span class="line"><span class="keyword">const</span> arr = <span class="title class_">Array</span>.<span class="title function_">from</span>(newNamesSet);</span><br><span class="line"><span class="comment">//更简单</span></span><br><span class="line"><span class="comment">// console.log([...new Set(names)]);</span></span><br><span class="line"><span class="comment">//size 里面元素的个数</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//add添加</span></span><br><span class="line">set.<span class="title function_">add</span>(<span class="number">100</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(set);</span><br><span class="line"></span><br><span class="line"><span class="comment">//delete 删除</span></span><br><span class="line">set.<span class="title function_">delete</span>(<span class="number">100</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(set);</span><br><span class="line"></span><br><span class="line"><span class="comment">//清空 clear</span></span><br><span class="line"><span class="comment">// set.clear();</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//has 有某个元素</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(set.<span class="title function_">has</span>(obj)); <span class="comment">//false</span></span><br><span class="line"></span><br><span class="line">set.<span class="title function_">forEach</span>(<span class="function">(<span class="params">item</span>) =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(item));</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> item <span class="keyword">of</span> set) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="4-2-WeakSet"><a href="#4-2-WeakSet" class="headerlink" title="4.2 WeakSet"></a>4.2 WeakSet</h3><p>weak Reference 弱引用:可以通过引用获取到对应的数据，但是他引用的那个对象不保证一定不被销毁.<br>strong Reference 强引用:我保证你引用的对象永远存在</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj1 = &#123; <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span> &#125;;</span><br><span class="line"><span class="keyword">let</span> obj2 = &#123; <span class="attr">name</span>: <span class="string">&#x27;jack&#x27;</span> &#125;;</span><br><span class="line"><span class="keyword">let</span> obj3 = &#123; <span class="attr">name</span>: <span class="string">&#x27;kern&#x27;</span> &#125;;</span><br><span class="line"><span class="keyword">let</span> arr = [obj1, obj2, obj3];</span><br><span class="line">obj1 = <span class="literal">null</span>;</span><br><span class="line">obj2 = <span class="literal">null</span>;</span><br><span class="line">obj3 = <span class="literal">null</span>;</span><br><span class="line"><span class="comment">//set对象对obj1 2 3 有引用，所以这三个对象不会被销毁</span></span><br><span class="line"><span class="keyword">const</span> set = <span class="keyword">new</span> <span class="title class_">Set</span>(arr);</span><br><span class="line">arr = <span class="literal">null</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(set);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> obj1 = &#123; <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span> &#125;;</span><br><span class="line"><span class="keyword">let</span> obj2 = &#123; <span class="attr">name</span>: <span class="string">&#x27;jack&#x27;</span> &#125;;</span><br><span class="line"><span class="keyword">let</span> obj3 = &#123; <span class="attr">name</span>: <span class="string">&#x27;kern&#x27;</span> &#125;;</span><br><span class="line"><span class="keyword">let</span> arr = [obj1, obj2, obj3];</span><br><span class="line"><span class="comment">// obj1 = null;</span></span><br><span class="line"><span class="comment">// obj2 = null;</span></span><br><span class="line"><span class="comment">// obj3 = null;</span></span><br><span class="line"><span class="keyword">const</span> weakset = <span class="keyword">new</span> <span class="title class_">WeakSet</span>();</span><br><span class="line"><span class="comment">//WeakSet只能添加对象不能存放基本数据类型</span></span><br><span class="line"><span class="comment">// weakset.add(123);</span></span><br><span class="line">weakset.<span class="title function_">add</span>(obj1);</span><br><span class="line">weakset.<span class="title function_">add</span>(obj2);</span><br><span class="line">weakset.<span class="title function_">add</span>(obj3);</span><br><span class="line"><span class="comment">//不一定能访问到，因为weakset是弱引用，里面的东西可能会被销毁掉</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj1);</span><br><span class="line"><span class="comment">//add  delete has</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//WeakSet不能遍历</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//应用 stackoverflow 集合</span></span><br><span class="line"><span class="keyword">const</span> pWeakSet = <span class="keyword">new</span> <span class="title class_">WeakSet</span>();</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params"></span>) &#123;</span><br><span class="line">    pWeakSet.<span class="title function_">add</span>(<span class="variable language_">this</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">//问题很大，放在类里面的方法，我只希望你的实例调用的</span></span><br><span class="line">  <span class="comment">//引用给谁 谁就能调用</span></span><br><span class="line">  <span class="comment">//限制一下 只让他的实例调用</span></span><br><span class="line">  <span class="title function_">running</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (!pWeakSet.<span class="title function_">has</span>(<span class="variable language_">this</span>)) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;type error 调用方式不对&#x27;</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;跑～&#x27;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//都能正常调用</span></span><br><span class="line"><span class="keyword">let</span> p = <span class="keyword">new</span> <span class="title class_">Person</span>();</span><br><span class="line">p.<span class="title function_">running</span>();</span><br><span class="line"><span class="keyword">const</span> fn = p.<span class="property">running</span>;</span><br><span class="line"><span class="title function_">fn</span>();</span><br><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">run</span>: p.<span class="property">running</span>,</span><br><span class="line">&#125;;</span><br><span class="line">obj.<span class="title function_">run</span>();</span><br><span class="line"><span class="comment">//为什么不用set，set强引用，p = null set里面的引用 一直在 对象一直在</span></span><br><span class="line"><span class="comment">//weakset 我想销毁 就能正常销毁</span></span><br></pre></td></tr></table></figure>

<p>WeakSet 只能存放对象类型，不能 add 基本类型<br>WeakSet 是弱引用。<br>WeakSet 不能遍历，原因是：WeakSet 是弱引用，如果遍历获取其中的元素，有可能导致对象不能正常的销毁。</p>
<h2 id="5-Map-映射"><a href="#5-Map-映射" class="headerlink" title="5. Map 映射"></a>5. Map 映射</h2><h3 id="5-1-Map"><a href="#5-1-Map" class="headerlink" title="5.1 Map"></a>5.1 Map</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//没有map 对象不能当作键名</span></span><br><span class="line"><span class="keyword">const</span> info = &#123; <span class="attr">name</span>: <span class="string">&#x27;alex&#x27;</span> &#125;;</span><br><span class="line"><span class="keyword">const</span> info2 = &#123; <span class="attr">name</span>: <span class="string">&#x27;jack&#x27;</span> &#125;;</span><br><span class="line"><span class="comment">// const obj = &#123;</span></span><br><span class="line"><span class="comment">//   address: &#x27;火星&#x27;,</span></span><br><span class="line"><span class="comment">//   [info]: &#x27;hhahah&#x27;,</span></span><br><span class="line"><span class="comment">//   [info2]: &#x27;嘻嘻嘻嘻&#x27;,</span></span><br><span class="line"><span class="comment">// &#125;;</span></span><br><span class="line"><span class="comment">// console.log(obj);</span></span><br><span class="line"><span class="comment">// //[object Object]是字符串，100%会遇到这个</span></span><br><span class="line"><span class="comment">// //我只能接受字符串，你却给我一个对象，我没办法了就展示成这样</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>();</span><br><span class="line"><span class="comment">//设置 set</span></span><br><span class="line">map.<span class="title function_">set</span>(info, <span class="string">&#x27;aaaa&#x27;</span>);</span><br><span class="line">map.<span class="title function_">set</span>(info2, <span class="string">&#x27;bbb&#x27;</span>);</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map);</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取 get</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">get</span>(info));</span><br><span class="line"></span><br><span class="line"><span class="comment">//删除 delete</span></span><br><span class="line"><span class="comment">// map.delete(info);</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 清空 clear()</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//has</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">has</span>(info));</span><br><span class="line"></span><br><span class="line"><span class="comment">//forEach 值</span></span><br><span class="line">map.<span class="title function_">forEach</span>(<span class="function">(<span class="params">item</span>) =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(item));</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">const</span> item <span class="keyword">of</span> map) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item); <span class="comment">//是数组</span></span><br><span class="line">  <span class="keyword">const</span> [key, value] = item;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;解构后&#x27;</span>, key, value);</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//map让对象可以作为key</span></span><br></pre></td></tr></table></figure>

<h3 id="5-2-WeakMap"><a href="#5-2-WeakMap" class="headerlink" title="5.2 WeakMap"></a>5.2 WeakMap</h3><p>区别一:WeakMap 只能用对象做 key，不接受其他类型<br>区别二:WeakMap 弱引用。</p>
<h2 id="Proxy-Reflect"><a href="#Proxy-Reflect" class="headerlink" title="Proxy-Reflect"></a>Proxy-Reflect</h2><h3 id="监听对象的操作（ES5）"><a href="#监听对象的操作（ES5）" class="headerlink" title="监听对象的操作（ES5）"></a>监听对象的操作（ES5）</h3><ul>
<li>首先<code>Object.defineProperty</code>设计的初衷，不是为了数据劫持和数据代理，也就是不是为了监听对象中所有的属性，详细地定义对象的属性，只不过我们的操作强行让它能够监听而已。</li>
<li>其次我们想监听一些更加丰富的操作的时候，没办法。所以 ES6 给我们提供了 proxy</li>
</ul>
<h3 id="监听对象的操作（ES6）"><a href="#监听对象的操作（ES6）" class="headerlink" title="监听对象的操作（ES6）"></a>监听对象的操作（ES6）</h3><p>Proxy 类，用于帮助我们创建一个代理，监听对象的时候，我们可以先创建一个代理对象(proxy)，之后所有对该对象的操作都通过代理对象来完成。<br><code>const p = new Proxy(target,handler)</code><br>target:你要代理的目标对象<br>hanlder:你需要做那些处理</p>
<p>set: 四个参数<br>target 目标对象<br>property 属性<br>value 值<br>receiver 调用的代理对象</p>
<p>get: 三个参数<br>target 目标对象<br>property 属性<br>receiver 调用的代理对象</p>
<h2 id="Reflect-和-Object"><a href="#Reflect-和-Object" class="headerlink" title="Reflect 和 Object"></a>Reflect 和 Object</h2><p>Reflect(反射)也是 ES6 新增的 API，它是一个对象。提供了操作对象的方法</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj = &#123;&#125;;</span><br><span class="line"><span class="comment">//确实可以这样做，但是不符合ecma标准</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj.<span class="property">__proto__</span>);</span><br><span class="line"><span class="comment">//按照ecma的标准</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">getPrototypeOf</span>(obj));</span><br><span class="line"></span><br><span class="line"><span class="comment">//还可以用reflect</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Reflect</span>.<span class="title function_">getPrototypeOf</span>(obj));</span><br></pre></td></tr></table></figure>

<ul>
<li>明明已经有 Object 可以做这些操作，为什么还要有 Reflect？这是因为早期 ECMA 规范没有考虑到对对象本身的操作如何设计 更加好。Object 在 js 内属于顶级的类，Array,Function,Number,String…都继承于他，从语言设计层面来说，作为所有类的父类，你本身不应该包含太多东西。</li>
<li>ES6 新增的 Reflect 就把一些操作集中到了 Reflect 对象上。Reflect 就是专门来做对象的操作用的,Proxy 也可以不操作原对象</li>
</ul>
<h2 id="Promise"><a href="#Promise" class="headerlink" title="Promise"></a>Promise</h2><h3 id="Promise-的概念"><a href="#Promise-的概念" class="headerlink" title="Promise 的概念"></a>Promise 的概念</h3><p>Promise 是一个类，承诺，许诺<br>当我们需要的时候，给予调用者一个承诺，待会给你回调的数据，就可以来创建一个 promise 的实例<br>通过 new 创建 Promise 对象的时候，传入了一个回调函数，称为</p>
<p>Promise是一个用来处理不会立即得到数据或结果（异步操作）的一个构造函数</p>
<p><strong>executor（执行函数）</strong></p>
<ul>
<li>这个回调函数会被立即执行，并且接受另外的两个回调函数 resolve，reject</li>
<li>当我们调用 resolve 时，会<strong>执行</strong> promise 对象的 then 方法传入的<strong>回调函数</strong></li>
<li>当我们调用 reject 时,会<strong>执行</strong> promise 对象的 catch 方法传入的<strong>回调函数</strong></li>
</ul>
<h3 id="promise-的三个状态"><a href="#promise-的三个状态" class="headerlink" title="promise 的三个状态"></a>promise 的三个状态</h3><ul>
<li>待定(pending):初始状态，即没有被兑现，也没有被拒绝；当执行 executor 中的代码时，处于该状态。</li>
<li>已兑现(fulfilled):意味着操作完成，执行了 resolve，处于该状态的话 promise 已经被兑现了</li>
<li>已拒绝(rejected):意味着操作失败，执行了 reject，处于该状态的话 promise 已经被拒绝了</li>
</ul>
<h3 id="executor（执行函数）"><a href="#executor（执行函数）" class="headerlink" title="executor（执行函数）"></a>executor（执行函数）</h3><p>我们往往会在 executor 中确定 promise 的状态-叫已决议<br>注意：<strong>一旦状态被确定下来，Promise 状态就会被锁死 🔒，该 Promise 的状态就不可变</strong>，在我们调用 resolve 的时候，如果 resolve 的值不是一个 Promise，那么会将该 Promise 的状态变成成功。resolve 调用之后再 reject 调用，reject 的代码会执行，但是不会改变 Promise 的状态，并不是不执行代码.</p>
<h3 id="resolve-参数的三种情况"><a href="#resolve-参数的三种情况" class="headerlink" title="resolve 参数的三种情况"></a>resolve 参数的三种情况</h3><h4 id="then"><a href="#then" class="headerlink" title="then"></a>then</h4><p>then 方法是返回一个全新的 promise，这个 promise 他的状态是等到 then 传入的回调函数有返回值时，再进行决议。</p>
<h4 id="finally"><a href="#finally" class="headerlink" title="finally"></a>finally</h4><p>ES9(ES2018)中新增的一个特性，无论你的 promise 对象是 fulfilled 还是 rejected 状态，最终都要执行的代码。finally 不接收参数。</p>
<h3 id="Promise的类方法"><a href="#Promise的类方法" class="headerlink" title="Promise的类方法"></a>Promise的类方法</h3><h4 id="Promise-resolve"><a href="#Promise-resolve" class="headerlink" title="Promise.resolve"></a>Promise.resolve</h4><p>最大的作用，就是把一个<strong>现成的内容转成 Promise</strong>来使用,就可以使用 Promise.resolve。<br>作为 resolve 来说，他的参数是有三种情况 04.html 讲过</p>
<h4 id="Promise-reject"><a href="#Promise-reject" class="headerlink" title="Promise.reject"></a>Promise.reject</h4><p>reject 方法类似于 resolve<br><strong>注意:不管传入 Promise.reject 的参数是何种形式，都会直接作为 rejected 状态给到 catch 的回调</strong></p>
<h2 id="其他类方法…"><a href="#其他类方法…" class="headerlink" title="其他类方法…"></a>其他类方法…</h2><p>都是处理多个 promise 的类方法<br>all allSettled any race</p>
<h2 id="async"><a href="#async" class="headerlink" title="async"></a>async</h2><p><code>async</code>关键字定义的函数叫做<strong>异步函数</strong>，返回一个<strong>Promise对象</strong></p>
<p>语法：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//普通写法</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123; &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//箭头函数写法</span></span><br><span class="line"><span class="keyword">let</span> <span class="title function_">bar</span>=<span class="keyword">async</span>(<span class="params"></span>)=&gt;&#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//在claas中的写法</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">foo</span> &#123;</span><br><span class="line">	<span class="keyword">async</span> <span class="title function_">bar</span>(<span class="params"></span>) &#123; &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="await"><a href="#await" class="headerlink" title="await"></a>await</h2><p><code>await</code>关键字必须和<code>async</code>一起使用才有效果。如果有多个await，则会等上一个await的promise对象的状态为兑现状态时，才会执行下一个await后面的表达式</p>
<p>特点:<code>await</code>会阻塞async函数后面代码的执行，直到await后面的表达式结果出来后才会执行后面的代码</p>
<p>await返回的值就是await后面表达式的值</p>
<ul>
<li>如果await后面表达式是一个普通值，则返回值就是这个普通值</li>
<li>如果await后面表达式是一个兑现状态（<em>fulfilled</em>）的promise对象，则返回值就是兑现状态的值</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params"></span>) &#123;</span><br><span class="line">	<span class="keyword">let</span> res1 = <span class="keyword">await</span> <span class="number">123</span></span><br><span class="line">	<span class="variable language_">console</span>.<span class="title function_">log</span>(res1);</span><br><span class="line">	<span class="keyword">let</span> res2 = <span class="keyword">await</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">reslove, reject</span>) =&gt;</span> &#123;</span><br><span class="line">       <span class="title function_">reslove</span>(<span class="string">&quot;success&quot;</span>)</span><br><span class="line">   	&#125;)</span><br><span class="line">	<span class="variable language_">console</span>.<span class="title function_">log</span>(res2);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">foo</span>()</span><br></pre></td></tr></table></figure>

</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="http://example.com">CoderT</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="http://example.com/2022/09/25/JavaScript%E9%AB%98%E9%98%B6/">http://example.com/2022/09/25/JavaScript%E9%AB%98%E9%98%B6/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="http://example.com" target="_blank">CoderT</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/JavaScript/">JavaScript</a></div><div class="post_share"><div class="social-share" data-image="https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-full"><a href="/2022/09/19/JavaScript%E5%9F%BA%E7%A1%80/" title="Javascript基础"><img class="cover" src="https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">Javascript基础</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/2022/09/19/JavaScript%E5%9F%BA%E7%A1%80/" title="Javascript基础"><img class="cover" src="https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-09-19</div><div class="title">Javascript基础</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="/img/avatar.png" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">CoderT</div><div class="author-info__description">一以贯之的努力，不得懈怠的人生</div></div><div class="card-info-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">2</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">1</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">1</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/T-oney666/T-oney666.github.io"><i class="fab fa-github"></i><span>加入我</span></a></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">这是我的博客，记录日常工作和学习中的内容。如有不对，请多指教！</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8E%9F%E5%9E%8B"><span class="toc-number">1.</span> <span class="toc-text">原型</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#prototype-%E6%98%BE%E7%A4%BA%E5%8E%9F%E5%9E%8B"><span class="toc-number">1.1.</span> <span class="toc-text">prototype 显示原型</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#proto-%E9%9A%90%E5%BC%8F%E5%8E%9F%E5%9E%8B"><span class="toc-number">1.2.</span> <span class="toc-text">__proto__ 隐式原型</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B0%8F%E7%BB%93"><span class="toc-number">1.3.</span> <span class="toc-text">小结</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%BC%80%E5%8F%91%E6%80%9D%E6%83%B3"><span class="toc-number">1.4.</span> <span class="toc-text">面向对象的开发思想</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%8E%9F%E5%9E%8B%E5%92%8C%E5%8E%9F%E5%9E%8B%E9%93%BE"><span class="toc-number">1.5.</span> <span class="toc-text">原型和原型链</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%B9%E8%B1%A1%E8%AE%BF%E9%97%AE%E6%9C%BA%E5%88%B6"><span class="toc-number">1.6.</span> <span class="toc-text">对象访问机制</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BB%A7%E6%89%BF"><span class="toc-number">2.</span> <span class="toc-text">继承</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-%E8%AE%A4%E8%AF%86%E7%BB%A7%E6%89%BF"><span class="toc-number">2.1.</span> <span class="toc-text">1. 认识继承</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-%E5%8E%9F%E5%9E%8B%E7%BB%A7%E6%89%BF"><span class="toc-number">2.2.</span> <span class="toc-text">2. 原型继承</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-call-%E7%BB%A7%E6%89%BF"><span class="toc-number">2.3.</span> <span class="toc-text">3. call 继承</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-%E7%BB%84%E5%90%88%E7%BB%A7%E6%89%BF"><span class="toc-number">2.4.</span> <span class="toc-text">4. 组合继承</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-es6-%E7%BB%A7%E6%89%BF"><span class="toc-number">2.5.</span> <span class="toc-text">5. es6 继承</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#js%E7%9A%84%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86"><span class="toc-number"></span> <span class="toc-text">js的运行原理</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#V8%E5%A6%82%E4%BD%95%E6%8A%8Ajs%E8%BF%90%E8%A1%8C%E8%B5%B7%E6%9D%A5"><span class="toc-number">1.</span> <span class="toc-text">V8如何把js运行起来</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#V8%E5%BC%95%E6%93%8E%E5%8E%9F%E7%90%86"><span class="toc-number">1.1.</span> <span class="toc-text">V8引擎原理</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#js%E4%BB%A3%E7%A0%81%E7%9A%84%E6%89%A7%E8%A1%8C"><span class="toc-number">1.1.1.</span> <span class="toc-text">js代码的执行</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E4%BB%80%E4%B9%88%E6%98%AFV8"><span class="toc-number">1.1.1.1.</span> <span class="toc-text">什么是V8</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#V8%E6%9E%B6%E6%9E%84"><span class="toc-number">1.1.1.2.</span> <span class="toc-text">V8架构</span></a></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#js%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87GO-AO-VO"><span class="toc-number">2.</span> <span class="toc-text">js执行上下文GO AO VO</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#2-1-%E5%88%9D%E5%A7%8B%E5%8C%96%E5%85%A8%E5%B1%80%E5%AF%B9%E8%B1%A1"><span class="toc-number">2.1.</span> <span class="toc-text">2.1 初始化全局对象</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2-%E6%89%A7%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87"><span class="toc-number">2.2.</span> <span class="toc-text">2.2 执行上下文</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-3-VO%E5%AF%B9%E8%B1%A1"><span class="toc-number">2.3.</span> <span class="toc-text">2.3 VO对象</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E8%A1%A5%E5%85%85%EF%BC%9AFunction-length%E5%B1%9E%E6%80%A7"><span class="toc-number">2.3.0.1.</span> <span class="toc-text">补充：Function.length属性</span></a></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%A8%E5%B1%80%E4%BB%A3%E7%A0%81%E5%A6%82%E4%BD%95%E6%89%A7%E8%A1%8C"><span class="toc-number">3.</span> <span class="toc-text">全局代码如何执行</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E7%9A%84-length-%E5%B1%9E%E6%80%A7"><span class="toc-number">3.0.0.1.</span> <span class="toc-text">函数的 length 属性</span></a></li></ol></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-%E5%87%BD%E6%95%B0%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C"><span class="toc-number">3.1.</span> <span class="toc-text">3.函数代码执行</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-%E5%87%BD%E6%95%B0%E4%BB%A3%E7%A0%81%E5%A4%9A%E6%AC%A1%E6%89%A7%E8%A1%8C"><span class="toc-number">3.2.</span> <span class="toc-text">4.函数代码多次执行</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-%E5%87%BD%E6%95%B0%E4%BB%A3%E7%A0%81%E4%BA%92%E7%9B%B8%E8%B0%83%E7%94%A8"><span class="toc-number">3.3.</span> <span class="toc-text">5. 函数代码互相调用</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B"><span class="toc-number">4.</span> <span class="toc-text">函数执行过程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8%E5%9F%9F%E5%92%8C%E4%BD%9C%E7%94%A8%E5%9F%9F%E9%93%BE"><span class="toc-number">5.</span> <span class="toc-text">作用域和作用域链</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#6-1-%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%E7%9A%84%E6%9F%A5%E6%89%BE%E9%A1%BA%E5%BA%8F"><span class="toc-number">5.0.1.</span> <span class="toc-text">6.1 全局变量的查找顺序</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#6-2-%E5%87%BD%E6%95%B0%E5%8F%98%E9%87%8F%E7%9A%84%E6%9F%A5%E6%89%BE%E9%A1%BA%E5%BA%8F"><span class="toc-number">5.0.2.</span> <span class="toc-text">6.2 函数变量的查找顺序</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E4%BD%9C%E7%94%A8%E5%9F%9F%E9%93%BE"><span class="toc-number">5.0.2.1.</span> <span class="toc-text">作用域链</span></a></li></ol></li><li class="toc-item toc-level-4"><a class="toc-link" href="#6-3-%E5%A4%9A%E5%B1%82%E5%B5%8C%E5%A5%97%E7%9A%84%E6%9F%A5%E6%89%BE%E9%A1%BA%E5%BA%8F"><span class="toc-number">5.0.3.</span> <span class="toc-text">6.3 多层嵌套的查找顺序</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#6-4-%E5%87%A0%E9%81%93%E7%BB%8F%E5%85%B8%E7%9A%84%E9%9D%A2%E8%AF%95%E9%A2%98"><span class="toc-number">5.0.4.</span> <span class="toc-text">6.4 几道经典的面试题</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#javascript-%E7%9A%84%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86"><span class="toc-number">6.</span> <span class="toc-text">javascript 的内存管理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-1-%E8%AE%A4%E8%AF%86%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86"><span class="toc-number">6.1.</span> <span class="toc-text">1.1 认识内存管理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-2-js-%E7%9A%84%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86"><span class="toc-number">6.2.</span> <span class="toc-text">1.2 js 的内存管理</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E6%9C%BA%E5%88%B6%E7%AE%97%E6%B3%95"><span class="toc-number">7.</span> <span class="toc-text">2. 垃圾回收机制算法</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#2-1-js-%E7%9A%84%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%EF%BC%88Garbage-Collection%EF%BC%89"><span class="toc-number">7.1.</span> <span class="toc-text">2.1 js 的垃圾回收（Garbage Collection）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2%E5%BC%95%E7%94%A8%E8%AE%A1%E6%95%B0%EF%BC%88Reference-counting%EF%BC%89"><span class="toc-number">7.2.</span> <span class="toc-text">2.2引用计数（Reference counting）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-3-%E6%A0%87%E8%AE%B0-%E6%B8%85%E9%99%A4-mark-Sweep"><span class="toc-number">7.3.</span> <span class="toc-text">2.3 标记-清除(mark-Sweep)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-4-%E5%B8%B8%E8%A7%81%E7%9A%84%E5%85%B6%E4%BB%96-GC-%E7%AE%97%E6%B3%95"><span class="toc-number">7.4.</span> <span class="toc-text">2.4 常见的其他 GC 算法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-5-V8-%E5%BC%95%E6%93%8E%E8%AF%A6%E7%BB%86%E5%86%85%E5%AD%98%E5%9B%BE"><span class="toc-number">7.5.</span> <span class="toc-text">2.5 V8 引擎详细内存图</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-%E9%97%AD%E5%8C%85"><span class="toc-number">8.</span> <span class="toc-text">3. 闭包</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#3-1-js-%E7%9A%84%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B"><span class="toc-number">8.1.</span> <span class="toc-text">3.1 js 的函数式编程</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-2-%E9%97%AD%E5%8C%85%E7%9A%84%E6%A6%82%E5%BF%B5"><span class="toc-number">8.2.</span> <span class="toc-text">3.2 闭包的概念</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-%E9%97%AD%E5%8C%85%E7%9A%84%E5%BD%A2%E6%88%90%E8%BF%87%E7%A8%8B"><span class="toc-number">9.</span> <span class="toc-text">4. 闭包的形成过程</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-%E9%97%AD%E5%8C%85%E7%9A%84%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F"><span class="toc-number">10.</span> <span class="toc-text">5. 闭包的内存泄漏</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#5-1-%E5%A6%82%E4%BD%95%E9%87%8A%E6%94%BE"><span class="toc-number">10.1.</span> <span class="toc-text">5.1 如何释放</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-2-%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F%E7%9A%84%E6%B5%8B%E8%AF%95"><span class="toc-number">10.2.</span> <span class="toc-text">5.2 内存泄漏的测试</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-3-AO-%E4%B8%8D%E4%BD%BF%E7%94%A8%E7%9A%84%E5%B1%9E%E6%80%A7%E4%BC%98%E5%8C%96"><span class="toc-number">10.3.</span> <span class="toc-text">5.3 AO 不使用的属性优化</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%87%BD%E6%95%B0%E7%9A%84%E5%A2%9E%E5%BC%BA%E7%9F%A5%E8%AF%86"><span class="toc-number">11.</span> <span class="toc-text">函数的增强知识</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-1-%E5%87%BD%E6%95%B0%E7%9A%84%E5%B1%9E%E6%80%A7%E5%92%8C-arguments"><span class="toc-number">11.1.</span> <span class="toc-text">1.1 函数的属性和 arguments</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1-1-1-%E5%87%BD%E6%95%B0%E7%9A%84%E5%B1%9E%E6%80%A7"><span class="toc-number">11.1.1.</span> <span class="toc-text">1.1.1 函数的属性</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-1-2-Arguments%E7%B1%BB%E6%95%B0%E7%BB%84%E5%AF%B9%E8%B1%A1"><span class="toc-number">11.1.2.</span> <span class="toc-text">1.1.2 Arguments类数组对象</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E7%9A%84-arguments"><span class="toc-number">11.1.2.1.</span> <span class="toc-text">箭头函数的 arguments</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#ES6%E7%9A%84Rest-parameters%EF%BC%88%E5%89%A9%E4%BD%99%E5%8F%82%E6%95%B0%EF%BC%89"><span class="toc-number">11.1.2.2.</span> <span class="toc-text">ES6的Rest parameters（剩余参数）</span></a></li></ol></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-2-%E7%BA%AF%E5%87%BD%E6%95%B0%E7%9A%84%E7%90%86%E8%A7%A3%E5%92%8C%E5%BA%94%E7%94%A8"><span class="toc-number">11.2.</span> <span class="toc-text">1.2 纯函数的理解和应用</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1-2-1-%E7%BA%AF%E5%87%BD%E6%95%B0%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-number">11.2.1.</span> <span class="toc-text">1.2.1 纯函数的理解</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-2-2-%E7%BA%AF%E5%87%BD%E6%95%B0%E7%9A%84%E4%BC%98%E5%8A%BF"><span class="toc-number">11.2.2.</span> <span class="toc-text">1.2.2 纯函数的优势</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-3-%E6%9F%AF%E9%87%8C%E5%8C%96%E7%9A%84%E7%90%86%E8%A7%A3%E5%92%8C%E5%BA%94%E7%94%A8"><span class="toc-number">11.3.</span> <span class="toc-text">1.3 柯里化的理解和应用</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1-3-1-%E6%9F%AF%E9%87%8C%E5%8C%96%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-number">11.3.1.</span> <span class="toc-text">1.3.1 柯里化的理解</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-3-2-%E6%9F%AF%E9%87%8C%E5%8C%96%E5%87%BD%E6%95%B0%E5%8F%98%E6%8D%A2"><span class="toc-number">11.3.2.</span> <span class="toc-text">1.3.2 柯里化函数变换</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-3-3-%E6%9F%AF%E9%87%8C%E5%8C%96%E5%87%BD%E6%95%B0%E4%BC%98%E5%8A%BF"><span class="toc-number">11.3.3.</span> <span class="toc-text">1.3.3 柯里化函数优势</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-3-4-%E6%9F%AF%E9%87%8C%E5%8C%96%E5%87%BD%E6%95%B0%E7%BB%83%E4%B9%A0"><span class="toc-number">11.3.4.</span> <span class="toc-text">1.3.4 柯里化函数练习</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-3-5-%E8%87%AA%E5%8A%A8%E6%9F%AF%E9%87%8C%E5%8C%96%E5%87%BD%E6%95%B0"><span class="toc-number">11.3.5.</span> <span class="toc-text">1.3.5 自动柯里化函数</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-4-%E7%BB%84%E5%90%88%E5%87%BD%E6%95%B0%E7%9A%84%E7%90%86%E8%A7%A3%E5%92%8C%E5%BA%94%E7%94%A8"><span class="toc-number">11.4.</span> <span class="toc-text">1.4 组合函数的理解和应用</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1-4-1-%E7%BB%84%E5%90%88%E5%87%BD%E6%95%B0%E6%A6%82%E5%BF%B5%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-number">11.4.1.</span> <span class="toc-text">1.4.1 组合函数概念的理解</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-4-2-%E8%87%AA%E5%8A%A8%E7%BB%84%E5%90%88%E5%87%BD%E6%95%B0"><span class="toc-number">11.4.2.</span> <span class="toc-text">1.4.2 自动组合函数</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-5-with%E3%80%81eval"><span class="toc-number">11.5.</span> <span class="toc-text">1.5 with、eval</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-6-%E4%B8%A5%E6%A0%BC%E6%A8%A1%E5%BC%8F"><span class="toc-number">11.6.</span> <span class="toc-text">1.6 严格模式</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-%E5%AF%B9%E8%B1%A1"><span class="toc-number">12.</span> <span class="toc-text">2.对象</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#2-1-Object-defineProperty"><span class="toc-number">12.1.</span> <span class="toc-text">2.1 Object.defineProperty</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2-%E4%B8%80%E4%BA%9B%E6%96%B0%E6%96%B9%E6%B3%95"><span class="toc-number">12.2.</span> <span class="toc-text">2.2 一些新方法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-%E5%AF%B9%E8%B1%A1%E6%96%B9%E6%B3%95%E7%9A%84%E8%A1%A5%E5%85%85"><span class="toc-number">13.</span> <span class="toc-text">1. 对象方法的补充</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-1-hasOwnProperty"><span class="toc-number">13.1.</span> <span class="toc-text">1.1 hasOwnProperty</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-2-in-%E6%93%8D%E4%BD%9C%E7%AC%A6"><span class="toc-number">13.2.</span> <span class="toc-text">1.2 in 操作符</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-3-instanceof"><span class="toc-number">13.3.</span> <span class="toc-text">1.3 instanceof</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-4-isPrototypeOf"><span class="toc-number">13.4.</span> <span class="toc-text">1.4 isPrototypeOf</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-class-%E6%96%B9%E5%BC%8F%E5%AE%9A%E4%B9%89%E7%B1%BB"><span class="toc-number">14.</span> <span class="toc-text">2. class 方式定义类</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#2-1-%E8%AE%A4%E8%AF%86-class-%E5%AE%9A%E4%B9%89%E7%B1%BB"><span class="toc-number">14.1.</span> <span class="toc-text">2.1 认识 class 定义类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2-class-%E7%B1%BB%E4%B8%AD%E7%9A%84%E5%86%85%E5%AE%B9"><span class="toc-number">14.2.</span> <span class="toc-text">2.2 class 类中的内容</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-3-%E7%B1%BB%E5%92%8C%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">14.3.</span> <span class="toc-text">2.3 类和构造函数的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-4-%E7%B1%BB%E7%9A%84%E8%AE%BF%E9%97%AE%E5%99%A8%E6%96%B9%E6%B3%95"><span class="toc-number">14.4.</span> <span class="toc-text">2.4 类的访问器方法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-extends-%E5%AE%9E%E7%8E%B0%E7%BB%A7%E6%89%BF"><span class="toc-number">15.</span> <span class="toc-text">3. extends 实现继承</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#3-1-%E7%BB%A7%E6%89%BF"><span class="toc-number">15.1.</span> <span class="toc-text">3.1 继承</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-2-super-%E5%85%B3%E9%94%AE%E5%AD%97"><span class="toc-number">15.2.</span> <span class="toc-text">3.2 super 关键字</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-3-%E7%BB%A7%E6%89%BF%E5%86%85%E7%BD%AE%E7%B1%BB"><span class="toc-number">15.3.</span> <span class="toc-text">3.3 继承内置类</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-%E5%A4%9A%E6%80%81%E6%A6%82%E5%BF%B5%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-number">16.</span> <span class="toc-text">4. 多态概念的理解</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-%E8%A1%A5%E5%85%85"><span class="toc-number">17.</span> <span class="toc-text">5. 补充</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#5-1-%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E7%9A%84%E5%A2%9E%E5%BC%BA%E5%86%99%E6%B3%95"><span class="toc-number">17.1.</span> <span class="toc-text">5.1 对象字面量的增强写法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-2-%E5%9B%9E%E9%A1%BE%E5%87%BD%E6%95%B0%E7%9A%84%E5%8E%9F%E5%9E%8B"><span class="toc-number">17.2.</span> <span class="toc-text">5.2 回顾函数的原型</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-3-%E6%89%8B%E5%86%99-apply"><span class="toc-number">17.3.</span> <span class="toc-text">5.3 手写 apply</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-4-%E6%89%8B%E5%86%99-call"><span class="toc-number">17.4.</span> <span class="toc-text">5.4 手写 call</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-5-call-apply-%E6%8A%BD%E5%8F%96%E5%B0%81%E8%A3%85"><span class="toc-number">17.5.</span> <span class="toc-text">5.5 call-apply 抽取封装</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%89%8B%E5%86%99-bind"><span class="toc-number">17.6.</span> <span class="toc-text">手写 bind</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#ES6"><span class="toc-number">18.</span> <span class="toc-text">ES6</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#1-%E5%87%BD%E6%95%B0"><span class="toc-number">19.</span> <span class="toc-text">1. 函数</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-1-%E9%BB%98%E8%AE%A4%E5%8F%82%E6%95%B0"><span class="toc-number">19.1.</span> <span class="toc-text">1.1 默认参数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#1-2-%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E8%A1%A5%E5%85%85"><span class="toc-number">19.2.</span> <span class="toc-text">1.2 箭头函数补充</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#2-%E5%B1%95%E5%BC%80%E8%BF%90%E7%AE%97%E7%AC%A6"><span class="toc-number">20.</span> <span class="toc-text">2. 展开运算符</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#2-1-%E5%B1%95%E5%BC%80%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8"><span class="toc-number">20.1.</span> <span class="toc-text">2.1 展开的基本使用</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-2-%E5%BC%95%E7%94%A8%E8%B5%8B%E5%80%BC%E5%92%8C%E6%B7%B1%E6%B5%85%E6%8B%B7%E8%B4%9D"><span class="toc-number">20.2.</span> <span class="toc-text">2.2 引用赋值和深浅拷贝</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#3-Symbol"><span class="toc-number">21.</span> <span class="toc-text">3. Symbol</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#3-1-%E5%88%9D%E8%AF%86-symbol"><span class="toc-number">21.1.</span> <span class="toc-text">3.1 初识 symbol</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-2-symbol-%E6%B3%A8%E6%84%8F%E5%92%8C-api"><span class="toc-number">21.2.</span> <span class="toc-text">3.2 symbol 注意和 api</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#4-Set-%E9%9B%86%E5%90%88"><span class="toc-number">22.</span> <span class="toc-text">4. Set 集合</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#4-1-set"><span class="toc-number">22.1.</span> <span class="toc-text">4.1 set</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-2-WeakSet"><span class="toc-number">22.2.</span> <span class="toc-text">4.2 WeakSet</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#5-Map-%E6%98%A0%E5%B0%84"><span class="toc-number">23.</span> <span class="toc-text">5. Map 映射</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#5-1-Map"><span class="toc-number">23.1.</span> <span class="toc-text">5.1 Map</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-2-WeakMap"><span class="toc-number">23.2.</span> <span class="toc-text">5.2 WeakMap</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Proxy-Reflect"><span class="toc-number">24.</span> <span class="toc-text">Proxy-Reflect</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%9B%91%E5%90%AC%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%93%8D%E4%BD%9C%EF%BC%88ES5%EF%BC%89"><span class="toc-number">24.1.</span> <span class="toc-text">监听对象的操作（ES5）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%9B%91%E5%90%AC%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%93%8D%E4%BD%9C%EF%BC%88ES6%EF%BC%89"><span class="toc-number">24.2.</span> <span class="toc-text">监听对象的操作（ES6）</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Reflect-%E5%92%8C-Object"><span class="toc-number">25.</span> <span class="toc-text">Reflect 和 Object</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#Promise"><span class="toc-number">26.</span> <span class="toc-text">Promise</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise-%E7%9A%84%E6%A6%82%E5%BF%B5"><span class="toc-number">26.1.</span> <span class="toc-text">Promise 的概念</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#promise-%E7%9A%84%E4%B8%89%E4%B8%AA%E7%8A%B6%E6%80%81"><span class="toc-number">26.2.</span> <span class="toc-text">promise 的三个状态</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#executor%EF%BC%88%E6%89%A7%E8%A1%8C%E5%87%BD%E6%95%B0%EF%BC%89"><span class="toc-number">26.3.</span> <span class="toc-text">executor（执行函数）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#resolve-%E5%8F%82%E6%95%B0%E7%9A%84%E4%B8%89%E7%A7%8D%E6%83%85%E5%86%B5"><span class="toc-number">26.4.</span> <span class="toc-text">resolve 参数的三种情况</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#then"><span class="toc-number">26.4.1.</span> <span class="toc-text">then</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#finally"><span class="toc-number">26.4.2.</span> <span class="toc-text">finally</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Promise%E7%9A%84%E7%B1%BB%E6%96%B9%E6%B3%95"><span class="toc-number">26.5.</span> <span class="toc-text">Promise的类方法</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Promise-resolve"><span class="toc-number">26.5.1.</span> <span class="toc-text">Promise.resolve</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Promise-reject"><span class="toc-number">26.5.2.</span> <span class="toc-text">Promise.reject</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%B6%E4%BB%96%E7%B1%BB%E6%96%B9%E6%B3%95%E2%80%A6"><span class="toc-number">27.</span> <span class="toc-text">其他类方法…</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#async"><span class="toc-number">28.</span> <span class="toc-text">async</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#await"><span class="toc-number">29.</span> <span class="toc-text">await</span></a></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/2022/09/25/JavaScript%E9%AB%98%E9%98%B6/" title="Javascript高阶"><img src="https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Javascript高阶"/></a><div class="content"><a class="title" href="/2022/09/25/JavaScript%E9%AB%98%E9%98%B6/" title="Javascript高阶">Javascript高阶</a><time datetime="2022-09-25T11:40:37.000Z" title="发表于 2022-09-25 19:40:37">2022-09-25</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2022/09/19/JavaScript%E5%9F%BA%E7%A1%80/" title="Javascript基础"><img src="https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Javascript基础"/></a><div class="content"><a class="title" href="/2022/09/19/JavaScript%E5%9F%BA%E7%A1%80/" title="Javascript基础">Javascript基础</a><time datetime="2022-09-19T06:40:37.000Z" title="发表于 2022-09-19 14:40:37">2022-09-19</time></div></div></div></div></div></div></main><footer id="footer" style="background-image: url('https://i.loli.net/2020/05/01/gkihqEjXxJ5UZ1C.jpg')"><div id="footer-wrap"><div class="copyright">&copy;2022 - 2023 By CoderT</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text">Hi, welcome to my <a target="_blank" rel="noopener" href="https://tonytop.top/">blog</a>!</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script>function panguFn () {
  if (typeof pangu === 'object') pangu.autoSpacingPage()
  else {
    getScript('https://cdn.jsdelivr.net/npm/pangu/dist/browser/pangu.min.js')
      .then(() => {
        pangu.autoSpacingPage()
      })
  }
}

function panguInit () {
  if (false){
    GLOBAL_CONFIG_SITE.isPost && panguFn()
  } else {
    panguFn()
  }
}

document.addEventListener('DOMContentLoaded', panguInit)</script><div class="js-pjax"></div><script defer="defer" id="fluttering_ribbon" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-fluttering-ribbon.min.js"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>